summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2012-11-30 14:01:38 +0000
committerJon TURNEY <jon.turney@dronecode.org.uk>2012-11-30 14:01:38 +0000
commit2e3122b5230284422be0001cd6a52c16ef707784 (patch)
treefadf8fd8b19ea605be000555be4a4a59b555ab09
XtoW
-rw-r--r--.gitignore78
-rw-r--r--COPYING339
-rw-r--r--Makefile.am1
-rwxr-xr-xautogen.sh12
-rw-r--r--configure.ac26
-rw-r--r--src/Makefile.am12
-rw-r--r--src/debug.c37
-rw-r--r--src/debug.h24
-rw-r--r--src/main.c124
-rw-r--r--src/win.c958
-rw-r--r--src/winmessages.h1054
11 files changed, 2665 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..15cf8eb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,78 @@
+#
+# X.Org module default exclusion patterns
+# The next section if for module specific patterns
+#
+# Do not edit the following section
+# GNU Build System (Autotools)
+aclocal.m4
+autom4te.cache/
+autoscan.log
+ChangeLog
+compile
+config.guess
+config.h
+config.h.in
+config.log
+config-ml.in
+config.py
+config.status
+config.status.lineno
+config.sub
+configure
+configure.scan
+depcomp
+.deps/
+INSTALL
+install-sh
+.libs/
+libtool
+libtool.m4
+ltmain.sh
+lt~obsolete.m4
+ltoptions.m4
+ltsugar.m4
+ltversion.m4
+Makefile
+Makefile.in
+mdate-sh
+missing
+mkinstalldirs
+*.pc
+py-compile
+stamp-h?
+symlink-tree
+texinfo.tex
+ylwrap
+
+# Do not edit the following section
+# Edit Compile Debug Document Distribute
+*~
+*.[0-9]
+*.[0-9]x
+*.bak
+*.bin
+core
+*.dll
+*.exe
+*-ISO*.bdf
+*-JIS*.bdf
+*-KOI8*.bdf
+*.kld
+*.ko
+*.ko.cmd
+*.lai
+*.l[oa]
+*.[oa]
+*.obj
+*.patch
+*.so
+*.pcf.gz
+*.pdb
+*.tar.bz2
+*.tar.gz
+#
+# Add & Override patterns for XtoW
+#
+# Edit the following section as needed
+# For example, !report.pc overrides *.pc. See 'man gitignore'
+#
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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
+
+ 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) <year> <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.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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) year 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 Lesser General
+Public License instead of this License.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..af437a6
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = src
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..904cd67
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+$srcdir/configure --enable-maintainer-mode "$@"
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..3cb8e91
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,26 @@
+AC_PREREQ(2.61)
+AC_INIT([XtoW], [0.1])
+
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+AM_CONFIG_HEADER([config.h])
+AM_SILENT_RULES([yes])
+
+# Initialize libtool
+AC_PROG_LIBTOOL
+
+# Require xorg-macros: XORG_DEFAULT_OPTIONS BASE_CFLAGS
+m4_ifndef([XORG_MACROS_VERSION],
+ [m4_fatal([must install xorg-macros 1.16 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.16)
+XORG_DEFAULT_OPTIONS
+
+# check for programs
+AC_PROG_CC
+AC_PROG_INSTALL
+
+# Checks for libraries.
+PKG_CHECK_MODULES(XCWM, xcwm)
+
+AC_CONFIG_FILES([Makefile
+ src/Makefile])
+AC_OUTPUT
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..1ca1a0d
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,12 @@
+AM_CFLAGS = $(XCWM_CFLAGS)
+
+bin_PROGRAMS = xtow
+
+xtow_SOURCES = \
+ main.c \
+ win.c \
+ debug.c \
+ debug.h \
+ winmessages.h
+
+xtow_LDADD = $(XCWM_LIBS) -lgdi32
diff --git a/src/debug.c b/src/debug.c
new file mode 100644
index 0000000..2761405
--- /dev/null
+++ b/src/debug.c
@@ -0,0 +1,37 @@
+//
+// Copyright © Jon TURNEY 2012
+//
+// This file is part of XtoW.
+//
+// XtoW 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.
+//
+// XtoW 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 XtoW. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "debug.h"
+
+#if 1
+int
+debug(const char *format, ...)
+{
+ int count;
+ va_list ap;
+ va_start(ap, format);
+ count = fprintf(stderr, "xtow: ");
+ count += vfprintf(stderr, format, ap);
+ va_end(ap);
+ return count;
+}
+#endif
diff --git a/src/debug.h b/src/debug.h
new file mode 100644
index 0000000..d446b77
--- /dev/null
+++ b/src/debug.h
@@ -0,0 +1,24 @@
+//
+// Copyright © Jon TURNEY 2012
+//
+// This file is part of XtoW.
+//
+// XtoW 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.
+//
+// XtoW 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 XtoW. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#if 1
+#define DEBUG debug
+#else
+#define DEBUG(Args...)
+#endif
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..01eb40f
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,124 @@
+//
+// Copyright Jon © TURNEY 2012
+//
+// This file is part of XtoW.
+//
+// XtoW 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.
+//
+// XtoW 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 XtoW. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <xcwm/xcwm.h>
+
+#include "debug.h"
+
+void
+eventHandler(const xcwm_event_t *event)
+{
+ xcwm_window_t *window = xcwm_event_get_window(event);
+ xcwm_event_type_t type = xcwm_event_get_type(event);
+
+ DEBUG("event %d, window 0x%08x, XID 0x%08x\n", type, window, window->window_id);
+
+ switch (type)
+ {
+ case XCWM_EVENT_WINDOW_CREATE:
+ winCreateWindowsWindow(window);
+ break;
+
+ case XCWM_EVENT_WINDOW_DESTROY:
+ winDestroyWindowsWindow(window);
+ break;
+
+ case XCWM_EVENT_WINDOW_NAME:
+ UpdateName(window);
+ break;
+
+ case XCWM_EVENT_WINDOW_DAMAGE:
+ UpdateImage(window);
+ break;
+
+ case XCWM_EVENT_WINDOW_EXPOSE: // I don't think this event could ever be needed and is a mistake
+ break;
+ }
+
+ free(event);
+}
+
+static void
+help(void)
+{
+ fprintf(stderr, "usage: xtow [options]\n");
+ fprintf(stderr, "-display dpy display to manage windows on\n");
+ fprintf(stderr, "-help\n");
+ exit(0);
+}
+
+int main(int argc, char **argv)
+{
+ char *screen = NULL;
+
+ while (1)
+ {
+ static struct option long_options[] =
+ {
+ { "display", required_argument, 0, 'd' },
+ { "help", no_argument, 0, 'h' },
+ {0, 0, 0, 0 },
+ };
+
+ int option_index = 0;
+ int c = getopt_long_only(argc, argv, "d:h", long_options, &option_index);
+
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 'd':
+ screen = optarg;
+ break;
+ case 'h':
+ default:
+ help();
+ }
+ }
+
+ if (optind < argc)
+ help();
+
+ DEBUG("screen is '%s'\n", screen);
+
+ xcwm_context_t *context = xcwm_context_open(screen);
+
+ // spawn the event loop thread, and set the callback function
+ xcwm_event_start_loop(context, eventHandler);
+
+ // Pump windows message queue
+ MSG msg;
+ while (GetMessage(&msg, NULL, 0, 0) > 0)
+ {
+ DispatchMessage(&msg);
+ }
+
+ // Shutdown:
+ // if we got WM_QUIT, message loop exits
+ // if server died, we get a error from xcb
+ // if window station is shutting down, we get WM_ENDSESSION
+ // if we got a signal...
+
+ xcwm_context_close(context);
+}
diff --git a/src/win.c b/src/win.c
new file mode 100644
index 0000000..527fa9a
--- /dev/null
+++ b/src/win.c
@@ -0,0 +1,958 @@
+//
+// Copyright © Jon TURNEY 2012
+//
+// This file is part of XtoW.
+//
+// XtoW 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.
+//
+// XtoW 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 XtoW. If not, see <http://www.gnu.org/licenses/>.
+//
+
+//
+// Lots of this stuff is ripped off from the existing integrated WM
+// in XWin
+//
+
+#include <windows.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <xcwm/xcwm.h>
+
+#include "debug.h"
+#include "winmessages.h"
+
+#define WINDOW_CLASS_X "xtow"
+#define WINDOW_TITLE_X "X"
+#define WIN_WID_PROP "cyg_wid_prop"
+#define WIN_XCWM_PROP "cyg_xcwm_prop"
+#define WIN_HDWP_PROP "cyg_hdwp_prop"
+
+/*
+ * ValidateSizing - Ensures size request respects hints
+ */
+static int
+ValidateSizing (HWND hwnd, xcwm_window_t *window,
+ WPARAM wParam, LPARAM lParam)
+{
+ RECT *rect = (RECT *)lParam;
+ int iWidth, iHeight;
+ RECT rcClient, rcWindow;
+ int iBorderWidthX, iBorderWidthY;
+
+ /* Invalid input checking */
+ if (lParam==0)
+ return FALSE;
+
+ iWidth = rect->right - rect->left;
+ iHeight = rect->bottom - rect->top;
+
+ /* Now remove size of any borders and title bar */
+ GetClientRect(hwnd, &rcClient);
+ GetWindowRect(hwnd, &rcWindow);
+ iBorderWidthX = (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left);
+ iBorderWidthY = (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top);
+ iWidth -= iBorderWidthX;
+ iHeight -= iBorderWidthY;
+
+ /* Constrain the size to legal values */
+ xcwm_window_constrain_sizing(window, &iWidth, &iHeight);
+
+ /* Add back the size of borders and title bar */
+ iWidth += iBorderWidthX;
+ iHeight += iBorderWidthY;
+
+ /* Adjust size according to where we're dragging from */
+ switch (wParam) {
+ case WMSZ_TOP:
+ case WMSZ_TOPRIGHT:
+ case WMSZ_BOTTOM:
+ case WMSZ_BOTTOMRIGHT:
+ case WMSZ_RIGHT:
+ rect->right = rect->left + iWidth;
+ break;
+ default:
+ rect->left = rect->right - iWidth;
+ break;
+ }
+
+ switch(wParam) {
+ case WMSZ_BOTTOM:
+ case WMSZ_BOTTOMRIGHT:
+ case WMSZ_BOTTOMLEFT:
+ case WMSZ_RIGHT:
+ case WMSZ_LEFT:
+ rect->bottom = rect->top + iHeight;
+ break;
+ default:
+ rect->top = rect->bottom - iHeight;
+ break;
+ }
+ return TRUE;
+}
+
+/*
+ * winAdjustXWindow
+ *
+ * Move and resize X window with respect to corresponding Windows window.
+ *
+ * This is when the user performs any windowing operation which might change
+ * it's size or position (create, move, resize, minimize, maximize, restore).
+ *
+ * The functionality is the inverse of winPositionWindowMultiWindow, which
+ * adjusts Windows window with respect to X window.
+ */
+int
+winAdjustXWindow (xcwm_window_t *window, HWND hWnd)
+{
+ RECT rcWin;
+ LONG x, y, w, h;
+
+#define WIDTH(rc) (rc.right - rc.left)
+#define HEIGHT(rc) (rc.bottom - rc.top)
+
+ if (IsIconic(hWnd))
+ {
+ DEBUG("Immediately return because the window is iconized\n");
+
+ /* XXX: match WM_STATE.state to state of Windows window */
+ /* XXX: send a WM_CHANGE_STATE message ? */
+
+ return 0;
+ }
+
+ /* Get size of client area */
+ GetClientRect(hWnd, &rcWin);
+ w = WIDTH(rcWin);
+ h = HEIGHT(rcWin);
+
+ /* Get virtual desktop coordinates of top-left of client area,
+ and transform to X screen coordinates */
+ POINT p = {0,0};
+ ClientToScreen(hWnd, &p);
+ x = p.x - GetSystemMetrics(SM_XVIRTUALSCREEN);
+ y = p.y - GetSystemMetrics(SM_YVIRTUALSCREEN);
+
+ DEBUG("ConfigureWindow to %ldx%ld @ (%ld, %ld)\n", w, h, x, y);
+
+ xcwm_window_configure(window, x, y, w, h);
+
+ return 1;
+
+#undef WIDTH
+#undef HEIGHT
+}
+
+/*
+ * Updates the name of a HWND according to its X WM_NAME property
+ */
+void
+UpdateName(xcwm_window_t *window)
+{
+ HWND hWnd = xcwm_window_get_local_data(window);
+ if (!hWnd)
+ return;
+
+ /* If window isn't override-redirect */
+ if (xcwm_window_is_override_redirect(window))
+ return;
+
+ char *name = xcwm_window_copy_name(window);
+ if (name)
+ {
+ DEBUG("UpdateName: '%s'\n", name);
+
+ /* Convert from UTF-8 to wide char */
+ int iLen = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
+ wchar_t *pwszWideWindowName = (wchar_t *) malloc(sizeof(wchar_t) * (iLen + 1));
+ MultiByteToWideChar(CP_UTF8, 0, name, -1, pwszWideWindowName, iLen);
+
+ /* Set the Windows window name */
+ SetWindowTextW(hWnd, pwszWideWindowName);
+
+ free(pwszWideWindowName);
+ free(name);
+ }
+}
+
+void
+UpdateImage(xcwm_window_t *window)
+{
+ HWND hWnd = xcwm_window_get_local_data(window);
+ if (!hWnd)
+ return;
+
+ xcwm_rect_t *dmgRect = xcwm_window_get_damaged_rect(window);
+
+ RECT damage;
+ damage.left = dmgRect->x;
+ damage.top = dmgRect->y;
+ damage.right = dmgRect->x + dmgRect->width;
+ damage.bottom = dmgRect->y + dmgRect->height;
+
+ InvalidateRect(hWnd, &damage, TRUE);
+}
+
+#if 0
+
+#define MwmHintsDecorations (1L << 1)
+
+#define MwmDecorAll (1L << 0)
+#define MwmDecorBorder (1L << 1)
+#define MwmDecorHandle (1L << 2)
+#define MwmDecorTitle (1L << 3)
+#define MwmDecorMenu (1L << 4)
+#define MwmDecorMinimize (1L << 5)
+#define MwmDecorMaximize (1L << 6)
+
+/* This structure only contains 3 elements... the Motif 2.0 structure
+contains 5... we only need the first 3... so that is all we will define */
+typedef struct MwmHints {
+ unsigned long flags, functions, decorations;
+} MwmHints;
+
+#define PropMwmHintsElements 3
+
+/* Windows window styles */
+#define HINT_NOFRAME (1l<<0)
+#define HINT_BORDER (1L<<1)
+#define HINT_SIZEBOX (1l<<2)
+#define HINT_CAPTION (1l<<3)
+#define HINT_NOMAXIMIZE (1L<<4)
+#define HINT_NOMINIMIZE (1L<<5)
+#define HINT_NOSYSMENU (1L<<6)
+#define HINT_SKIPTASKBAR (1L<<7)
+/* These two are used on their own */
+#define HINT_MAX (1L<<0)
+#define HINT_MIN (1L<<1)
+
+static void
+winApplyHints(xcb_drawable_t id, HWND hWnd, HWND *zstyle)
+{
+ static xcb_atom_t windowState, motif_wm_hints, windowType;
+ static xcb_atom_t hiddenState, fullscreenState, belowState, aboveState, skiptaskbarState;
+ static xcb_atom_t dockWindow;
+ static bool got_atoms = FALSE;
+ unsigned long hint = 0, maxmin = 0;
+ int nitems = 0;
+ unsigned long style, exStyle;
+ xcb_get_property_reply_t *reply;
+
+ *zstyle = HWND_NOTOPMOST;
+
+ if (!hWnd)
+ return;
+ if (!IsWindow(hWnd))
+ return;
+
+ if (!got_atoms)
+ {
+ windowState = atom_get(conn, "_NET_WM_STATE");
+ motif_wm_hints = atom_get(conn, "_MOTIF_WM_HINTS");
+ windowType = atom_get(conn, "_NET_WM_WINDOW_TYPE");
+ hiddenState = atom_get(conn, "_NET_WM_STATE_HIDDEN");
+ fullscreenState = atom_get(conn, "_NET_WM_STATE_FULLSCREEN");
+ belowState = atom_get(conn, "_NET_WM_STATE_BELOW");
+ aboveState = atom_get(conn, "_NET_WM_STATE_ABOVE");
+ dockWindow = atom_get(conn, "_NET_WM_WINDOW_TYPE_DOCK");
+ skiptaskbarState = atom_get(conn, "_NET_WM_STATE_SKIP_TASKBAR");
+ got_atoms = TRUE;
+ }
+
+ xcb_get_property_cookie_t cookie_wm_state = xcb_get_property(conn, FALSE, id, windowState, XCB_ATOM, 0L, INT_MAX);
+ xcb_get_property_cookie_t cookie_mwm_hint = xcb_get_property(conn, FALSE, id, motif_wm_hints, motif_wm_hints, 0L, PropMwmHintsElements);
+ xcb_get_property_cookie_t cookie_wm_window_type = xcb_get_property(conn, FALSE, id, windowType, XCB_ATOM, 0L, 1L);
+ xcb_get_property_cookie_t cookie_normal_hints = xcb_icccm_get_wm_normal_hints(conn, id);
+
+ if ((reply = xcb_get_property_reply(conn, cookie_wm_state, NULL)))
+ {
+ int i;
+ nitems = xcb_get_property_value_length(reply);
+ xcb_atom_t *pAtom = xcb_get_property_value(reply);
+
+ for (i = 0; i < nitems; i++)
+ {
+ if (pAtom[i] == skiptaskbarState)
+ hint |= HINT_SKIPTASKBAR;
+ if (pAtom[i] == hiddenState)
+ maxmin |= HINT_MIN;
+ else if (pAtom[i] == fullscreenState)
+ maxmin |= HINT_MAX;
+ if (pAtom[i] == belowState)
+ *zstyle = HWND_BOTTOM;
+ else if (pAtom[i] == aboveState)
+ *zstyle = HWND_TOPMOST;
+ }
+
+ free(reply);
+ }
+
+ if ((reply = xcb_get_property_reply(conn, cookie_mwm_hint, NULL)))
+ {
+ nitems = xcb_get_property_value_length(reply);
+ MwmHints *mwm_hint = xcb_get_property_value(reply);
+
+ if (mwm_hint && (nitems == PropMwmHintsElements) && (mwm_hint->flags & MwmHintsDecorations))
+ {
+ if (!mwm_hint->decorations)
+ hint |= HINT_NOFRAME;
+ else if (!(mwm_hint->decorations & MwmDecorAll))
+ {
+ if (mwm_hint->decorations & MwmDecorBorder)
+ hint |= HINT_BORDER;
+ if (mwm_hint->decorations & MwmDecorHandle)
+ hint |= HINT_SIZEBOX;
+ if (mwm_hint->decorations & MwmDecorTitle)
+ hint |= HINT_CAPTION;
+ if (!(mwm_hint->decorations & MwmDecorMenu))
+ hint |= HINT_NOSYSMENU;
+ if (!(mwm_hint->decorations & MwmDecorMinimize))
+ hint |= HINT_NOMINIMIZE;
+ if (!(mwm_hint->decorations & MwmDecorMaximize))
+ hint |= HINT_NOMAXIMIZE;
+ }
+ else
+ {
+ /*
+ MwmDecorAll means all decorations *except* those specified by other flag
+ bits that are set. Not yet implemented.
+ */
+ }
+ }
+
+ free(reply);
+ }
+
+ if ((reply = xcb_get_property_reply(conn, cookie_wm_window_type, NULL)))
+ {
+ nitems = xcb_get_property_value_length(reply);
+ xcb_atom_t *pAtom = xcb_get_property_value(reply);
+
+ if (pAtom && nitems == 1)
+ {
+ if (*pAtom == dockWindow)
+ {
+ /* puts a sizebox on dock windows */
+ hint = (hint & ~HINT_NOFRAME) | HINT_SIZEBOX;
+ *zstyle = HWND_TOPMOST;
+ }
+ }
+
+ free(reply);
+ }
+
+ {
+ xcb_size_hints_t normal_hint;
+
+ if (xcb_icccm_get_wm_normal_hints_reply(conn, cookie_normal_hints, &normal_hint, NULL))
+ {
+ if (normal_hint.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE)
+ {
+ /* Not maximizable if a maximum size is specified */
+ hint |= HINT_NOMAXIMIZE;
+
+ if (normal_hint.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE)
+ {
+ /*
+ If both minimum size and maximum size are specified and are the same,
+ don't bother with a resizing frame
+ */
+ if ((normal_hint.min_width == normal_hint.max_width)
+ && (normal_hint.min_height == normal_hint.max_height))
+ hint = (hint & ~HINT_SIZEBOX);
+ }
+ }
+ }
+ }
+
+ /* XXX: Override hint settings from above with settings from config file */
+ /* XXX: set application id from class hint for native window grouping */
+
+ /* XXX: this should only happen on initial show */
+ if (maxmin & HINT_MAX)
+ SendMessage(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
+ else if (maxmin & HINT_MIN)
+ SendMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+
+ /* Now apply styles to window */
+ style = GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION & ~WS_SIZEBOX; /* Just in case */
+ if (!style)
+ return; /* GetWindowLongPointer returns 0 on failure, we hope this isn't a valid style */
+
+ if (!(hint & ~HINT_SKIPTASKBAR)) /* All on */
+ style = style | WS_CAPTION | WS_SIZEBOX;
+ else if (hint & HINT_NOFRAME) /* All off */
+ style = style & ~WS_CAPTION & ~WS_SIZEBOX;
+ else
+ style = style | ((hint & HINT_BORDER) ? WS_BORDER : 0) |
+ ((hint & HINT_SIZEBOX) ? WS_SIZEBOX : 0) |
+ ((hint & HINT_CAPTION) ? WS_CAPTION : 0);
+
+ if (hint & HINT_NOMAXIMIZE)
+ style = style & ~WS_MAXIMIZEBOX;
+
+ if (hint & HINT_NOMINIMIZE)
+ style = style & ~WS_MINIMIZEBOX;
+
+ if (hint & HINT_NOSYSMENU)
+ style = style & ~WS_SYSMENU;
+
+ if (hint & HINT_SKIPTASKBAR)
+ style = style & ~WS_MINIMIZEBOX; /* otherwise, window will become lost if minimized */
+
+ SetWindowLongPtr(hWnd, GWL_STYLE, style);
+
+ exStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
+ if (hint & HINT_SKIPTASKBAR)
+ exStyle = (exStyle & ~WS_EX_APPWINDOW) | WS_EX_TOOLWINDOW;
+ else
+ exStyle = (exStyle & ~WS_EX_TOOLWINDOW) | WS_EX_APPWINDOW;
+ SetWindowLongPtr(hWnd, GWL_EXSTYLE, exStyle);
+
+ DEBUG("winApplyHints: id 0x%08x hints 0x%08x style 0x%08x exstyle 0x%08x\n",
+ id, hint, style, exStyle);
+}
+
+/*
+ * Updates the style of a HWND according to its X style properties
+ */
+static void
+UpdateStyle(struct client *pWin)
+{
+ HWND hWnd = pWin->hWnd;
+ HWND zstyle = HWND_NOTOPMOST;
+ UINT flags;
+#if 0
+ bool onTaskbar;
+#endif
+
+ /* Determine the Window style */
+ winApplyHints(pWin->id, hWnd, &zstyle);
+ winUpdateWindowPosition(hWnd, &zstyle);
+
+ /* Apply the updated window style, without changing it's show or activation state */
+ flags = SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
+ if (zstyle == HWND_NOTOPMOST)
+ flags |= SWP_NOZORDER | SWP_NOOWNERZORDER;
+ SetWindowPos(hWnd, NULL, 0, 0, 0, 0, flags);
+
+#if 0
+ /*
+ Use the WS_EX_TOOLWINDOW style to remove window from Alt-Tab window switcher
+
+ According to MSDN, this is supposed to remove the window from the taskbar as well,
+ if we SW_HIDE before changing the style followed by SW_SHOW afterwards.
+
+ But that doesn't seem to work reliably, so also use iTaskbarList interface to
+ tell the taskbar to show or hide this window.
+ */
+ onTaskbar = GetWindowLongPtr(hWnd, GWL_EXSTYLE) & WS_EX_APPWINDOW;
+ wintaskbar(hWnd, onTaskbar);
+
+ /* Check urgency hint */
+ winApplyUrgency(pWMInfo->pDisplay, iWindow, hWnd);
+#endif
+}
+
+#endif
+
+/* Don't allow window decoration to disappear off to top-left */
+void
+BumpWindowPosition(HWND hWnd)
+{
+ WINDOWINFO wi;
+ int iDx, iDy;
+
+ wi.cbSize = sizeof(WINDOWINFO);
+ GetWindowInfo(hWnd, &wi);
+
+ if (wi.rcWindow.left < GetSystemMetrics(SM_XVIRTUALSCREEN))
+ {
+ iDx = GetSystemMetrics(SM_XVIRTUALSCREEN) - wi.rcWindow.left;
+ wi.rcWindow.left += iDx;
+ wi.rcWindow.right += iDx;
+ }
+
+ if (wi.rcWindow.top < GetSystemMetrics(SM_YVIRTUALSCREEN))
+ {
+ iDy = GetSystemMetrics(SM_YVIRTUALSCREEN) - wi.rcWindow.top;
+ wi.rcWindow.top += iDy;
+ wi.rcWindow.bottom += iDy;
+ }
+
+ /* Position the Windows window */
+ SetWindowPos(hWnd, 0, wi.rcWindow.left, wi.rcWindow.top, wi.rcWindow.right - wi.rcWindow.left, wi.rcWindow.bottom - wi.rcWindow.top,
+ SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
+}
+
+static void
+winDebugWin32Message(const char* function, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static int force = 1;
+
+ if (message >= WM_USER)
+ {
+ if (force || getenv("WIN_DEBUG_MESSAGES") || getenv("WIN_DEBUG_WM_USER"))
+ {
+ DEBUG("%s: hWnd 0x%08x wParam 0x%08x lParam 0x%08x message WM_USER + %d\n",
+ function, hWnd, wParam, lParam, message - WM_USER);
+ }
+ }
+ else if (message < MESSAGE_NAMES_LEN && MESSAGE_NAMES[message])
+ {
+ const char *msgname = MESSAGE_NAMES[message];
+ char buffer[64];
+ snprintf(buffer, sizeof(buffer), "WIN_DEBUG_%s", msgname);
+ buffer[63] = 0;
+ if (force || getenv("WIN_DEBUG_MESSAGES") || getenv(buffer))
+ {
+ DEBUG("%s: hWnd 0x%08x wParam 0x%08x lParam 0x%08x message %s\n",
+ function, hWnd, wParam, lParam, MESSAGE_NAMES[message]);
+ }
+ }
+}
+
+/*
+ * winTopLevelWindowProc - Window procedure for all top-level Windows windows.
+ */
+
+LRESULT CALLBACK
+winTopLevelWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static bool hasEnteredSizeMove = FALSE;
+
+ winDebugWin32Message("winTopLevelWindowProc", hWnd, message, wParam, lParam);
+
+ if (message == WM_CREATE)
+ {
+ /* Store the xcwm window handle and X window XID in a Windows window properties */
+ xcwm_window_t *window = ((LPCREATESTRUCT)lParam)->lpCreateParams;
+ SetProp(hWnd, WIN_XCWM_PROP, window);
+ SetProp(hWnd, WIN_WID_PROP, (HANDLE)window->window_id);
+ return 0;
+ }
+
+ xcwm_window_t *window = (xcwm_window_t *)GetProp(hWnd, WIN_XCWM_PROP);
+
+ switch (message)
+ {
+ case WM_ACTIVATE:
+ /* If we are being activated, acquire the input focus */
+ if (LOWORD(wParam) != WA_INACTIVE)
+ {
+ xcwm_window_set_input_focus(window);
+ }
+ return 0;
+
+ case WM_ACTIVATEAPP:
+ /* If focus is going to another Windows app, no X window has the X input focus */
+ if (!wParam)
+ {
+ xcwm_window_set_input_focus(NULL);
+ }
+
+ case WM_MOUSEACTIVATE:
+ /* ??? override-redirect windows should not mouse-activate */
+ break;
+
+ case WM_CLOSE:
+ xcwm_window_request_close(window);
+ return 0;
+
+ case WM_DESTROY:
+ RemoveProp(hWnd, WIN_WID_PROP);
+ RemoveProp(hWnd, WIN_XCWM_PROP);
+ RemoveProp(hWnd, WIN_HDWP_PROP);
+ break;
+
+ case WM_MOVE:
+ /* Adjust the X Window to the moved Windows window */
+ if (!hasEnteredSizeMove)
+ winAdjustXWindow(window, hWnd);
+ /* else: Wait for WM_EXITSIZEMOVE */
+ return 0;
+
+ case WM_SIZE:
+ if (!hasEnteredSizeMove)
+ {
+ /* Adjust the X Window to the moved Windows window */
+ winAdjustXWindow(window, hWnd);
+ }
+ /* else: wait for WM_EXITSIZEMOVE */
+ return 0;
+
+ case WM_SIZING:
+ /* Need to legalize the size according to WM_NORMAL_HINTS */
+ return ValidateSizing(hWnd, window, wParam, lParam);
+
+ case WM_ENTERSIZEMOVE:
+ hasEnteredSizeMove = TRUE;
+ return 0;
+
+ case WM_EXITSIZEMOVE:
+ /* Adjust the X Window to the moved Windows window */
+ hasEnteredSizeMove = FALSE;
+ winAdjustXWindow(window, hWnd);
+ return 0;
+
+ case WM_SHOWWINDOW:
+ /* ??? */
+ break;
+
+ case WM_WINDOWPOSCHANGED:
+ /* ??? handle Z-order changes by reflecting to X */
+
+ /*
+ * Pass the message to DefWindowProc to let the function
+ * break down WM_WINDOWPOSCHANGED to WM_MOVE and WM_SIZE.
+ */
+ break;
+
+ case WM_STYLECHANGING:
+ /*
+ When the style changes, adjust the Windows window size so the client area remains the same size,
+ and adjust the Windows window position so that the client area remains in the same place.
+ */
+ {
+ RECT newWinRect;
+ DWORD dwExStyle;
+ DWORD dwStyle;
+ DWORD newStyle = ((STYLESTRUCT *) lParam)->styleNew;
+ WINDOWINFO wi;
+ HDWP hDwp;
+
+ dwExStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
+ dwStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
+
+ DEBUG("winTopLevelWindowProc: WM_STYLECHANGING from %08x %08x\n", dwStyle, dwExStyle);
+
+ if (wParam == (WPARAM)GWL_EXSTYLE)
+ dwExStyle = newStyle;
+
+ if (wParam == (WPARAM)GWL_STYLE)
+ dwStyle = newStyle;
+
+ DEBUG("winTopLevelWindowProc: WM_STYLECHANGING to %08x %08x\n", dwStyle, dwExStyle);
+
+ /* Get client rect in screen coordinates */
+ wi.cbSize = sizeof(WINDOWINFO);
+ GetWindowInfo(hWnd, &wi);
+
+ DEBUG("winTopLevelWindowProc: WM_STYLECHANGING client area {%d, %d, %d, %d}, {%d x %d}\n",
+ wi.rcClient.left, wi.rcClient.top, wi.rcClient.right,
+ wi.rcClient.bottom, wi.rcClient.right - wi.rcClient.left,
+ wi.rcClient.bottom - wi.rcClient.top);
+
+ newWinRect = wi.rcClient;
+ if (!AdjustWindowRectEx(&newWinRect, dwStyle, FALSE, dwExStyle))
+ DEBUG("winTopLevelWindowProc: WM_STYLECHANGING AdjustWindowRectEx failed\n");
+
+ DEBUG("winTopLevelWindowProc: WM_STYLECHANGING window area should be {%d, %d, %d, %d}, {%d x %d}\n",
+ newWinRect.left, newWinRect.top, newWinRect.right,
+ newWinRect.bottom, newWinRect.right - newWinRect.left,
+ newWinRect.bottom - newWinRect.top);
+
+ /*
+ Style change hasn't happened yet, so we can't adjust the window size yet, as the winAdjustXWindow()
+ which WM_SIZE does will use the current (unchanged) style. Instead make a note to change it when
+ WM_STYLECHANGED is received...
+ */
+ hDwp = BeginDeferWindowPos(1);
+ hDwp = DeferWindowPos(hDwp, hWnd, NULL, newWinRect.left,
+ newWinRect.top, newWinRect.right - newWinRect.left,
+ newWinRect.bottom - newWinRect.top,
+ SWP_NOACTIVATE | SWP_NOZORDER);
+ SetProp(hWnd, WIN_HDWP_PROP, (HANDLE)hDwp);
+ }
+ return 0;
+
+ case WM_STYLECHANGED:
+ {
+ HDWP hDwp = GetProp(hWnd, WIN_HDWP_PROP);
+ if (hDwp)
+ {
+ EndDeferWindowPos(hDwp);
+ RemoveProp(hWnd, WIN_HDWP_PROP);
+ }
+ DEBUG("winTopLevelWindowProc: WM_STYLECHANGED done\n");
+ }
+ return 0;
+
+ case WM_ERASEBKGND:
+ /* Since we are going to blit to the entire invalidated region,
+ there's no point erasing to background first */
+ return TRUE;
+
+ case WM_PAINT:
+ {
+ HDC hdcUpdate;
+ PAINTSTRUCT ps;
+ hdcUpdate = BeginPaint(hWnd, &ps);
+
+ /* Don't do anything if the PAINTSTRUCT is bogus */
+ if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 &&
+ ps.rcPaint.left == 0 && ps.rcPaint.top == 0)
+ {
+ }
+ else
+ {
+ /* XXX: just eat it for now... */
+ ValidateRect(hWnd, &(ps.rcPaint));
+
+ /* stop xcwm processing events so it doesn't can't change
+ this damage while we are using it */
+ xcwm_event_get_thread_lock();
+
+ xcwm_image_t *image;
+ image = xcwm_image_copy_damaged(window);
+ if (image)
+ {
+ xcwm_rect_t *winRect = xcwm_window_get_full_rect(window);
+ xcwm_rect_t *dmgRect = xcwm_window_get_damaged_rect(window);
+
+ // convert xcwm_image_t to something we can draw...
+
+ // Remove the damage
+ xcwm_window_remove_damage(window);
+ }
+ xcwm_event_release_thread_lock();
+ }
+
+ EndPaint(hWnd, &ps);
+ return 0;
+ }
+
+ }
+
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+/*
+ * winInitMultiWindowClass - Register our Window class
+ */
+static
+void winInitMultiWindowClass(void)
+{
+ static ATOM atomXWinClass = 0;
+ WNDCLASSEX wcx;
+
+ if (atomXWinClass == 0)
+ {
+ wcx.cbSize = sizeof(WNDCLASSEX);
+ wcx.style = CS_HREDRAW | CS_VREDRAW;
+ wcx.lpfnWndProc = winTopLevelWindowProc;
+ wcx.cbClsExtra = 0;
+ wcx.cbWndExtra = 0;
+ wcx.hInstance = GetModuleHandle(NULL);
+ wcx.hIcon = NULL;
+ wcx.hCursor = 0;
+ wcx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
+ wcx.lpszMenuName = NULL;
+ wcx.lpszClassName = WINDOW_CLASS_X;
+ wcx.hIconSm = NULL;
+
+ DEBUG("Creating class: %s\n", WINDOW_CLASS_X);
+
+ atomXWinClass = RegisterClassEx (&wcx);
+ }
+}
+
+/*
+ * winCreateWindowsWindow - Create a Windows window associated with an X window
+ */
+void
+winCreateWindowsWindow(xcwm_window_t *window)
+{
+ int iX, iY, iWidth, iHeight;
+ HWND hWnd;
+ HWND hFore = NULL;
+ DWORD dwStyle, dwExStyle;
+ RECT rc;
+
+ winInitMultiWindowClass();
+
+ DEBUG("winCreateWindowsWindow: window 0x%08x XID 0x%08x\n", window, window->window_id);
+
+ xcwm_rect_t *windowSize = xcwm_window_get_full_rect(window);
+ iX = windowSize->x + GetSystemMetrics(SM_XVIRTUALSCREEN);
+ iY = windowSize->y + GetSystemMetrics(SM_YVIRTUALSCREEN);
+ iWidth = windowSize->width;
+ iHeight = windowSize->height;
+
+#if 0
+ // XXX: xcwm can probably just ignore input only windows...
+ xcb_get_window_attributes_reply_t *attr;
+ attr = xcb_get_window_attributes_reply(conn, xcb_get_window_attributes(conn, pWin->id), NULL);
+
+ /* If it's an InputOutput window, and so is going to end up being made visible,
+ make sure the window actually ends up somewhere where it will be visible */
+ if (attr->_class != XCB_WINDOW_CLASS_INPUT_ONLY)
+ {
+ if ((iX < GetSystemMetrics (SM_XVIRTUALSCREEN)) || (iX > GetSystemMetrics (SM_CXVIRTUALSCREEN)))
+ iX = CW_USEDEFAULT;
+
+ if ((iY < GetSystemMetrics (SM_YVIRTUALSCREEN)) || (iY > GetSystemMetrics (SM_CYVIRTUALSCREEN)))
+ iY = CW_USEDEFAULT;
+ }
+#endif
+
+ DEBUG("winCreateWindowsWindow: %dx%d @ %dx%d\n", iWidth, iHeight, iX, iY);
+
+ const xcwm_window_t *parent = xcwm_window_get_transient_for(window);
+ if (parent)
+ {
+ /*
+ If we are transient-for another window, get the parent windows HWND
+ */
+ hFore = xcwm_window_get_local_data(parent);
+ }
+ else
+ {
+ /* Default positions if none specified */
+ if (!xcwm_window_is_override_redirect(window))
+ {
+#if 0
+ if (!(pWin->size_hints.flags & (XCB_ICCCM_SIZE_HINT_US_POSITION | XCB_ICCCM_SIZE_HINT_P_POSITION)))
+ {
+ iX = CW_USEDEFAULT;
+ iY = CW_USEDEFAULT;
+ }
+#endif
+ }
+ }
+
+ /* Make it WS_OVERLAPPED in create call since WS_POPUP doesn't support */
+ /* CW_USEDEFAULT, change back to popup after creation */
+ dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+ dwExStyle = WS_EX_TOOLWINDOW;
+
+ /*
+ Calculate the window coordinates containing the requested client area,
+ being careful to preseve CW_USEDEFAULT
+ */
+ rc.top = (iY != (int)CW_USEDEFAULT) ? iY : 0;
+ rc.left = (iX != (int)CW_USEDEFAULT) ? iX : 0;
+ rc.bottom = rc.top + iHeight;
+ rc.right = rc.left + iWidth;
+ AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle);
+ if (iY != (int)CW_USEDEFAULT) iY = rc.top;
+ if (iX != (int)CW_USEDEFAULT) iX = rc.left;
+ iHeight = rc.bottom - rc.top;
+ iWidth = rc.right - rc.left;
+
+ DEBUG("winCreateWindowsWindow: %dx%d @ %dx%d\n", iWidth, iHeight, iX, iY);
+
+ /* Create the window */
+ hWnd = CreateWindowExA(dwExStyle, /* Extended styles */
+ WINDOW_CLASS_X, /* Class name */
+ WINDOW_TITLE_X, /* Window name */
+ dwStyle, /* Styles */
+ iX, /* Horizontal position */
+ iY, /* Vertical position */
+ iWidth, /* Right edge */
+ iHeight, /* Bottom edge */
+ hFore, /* Null or Parent window if transient-for */
+ (HMENU) NULL, /* No menu */
+ GetModuleHandle(NULL), /* Instance handle */
+ (LPVOID)window); /* xcwm window handle */
+ if (hWnd == NULL)
+ {
+ fprintf(stderr, "CreateWindowExA() failed: %d\n", (int) GetLastError());
+ }
+
+ /* save the HWND into the context */
+ xcwm_window_set_local_data(window, hWnd);
+
+#if 0
+ /* Set icons */
+ HICON hIcon;
+ HICON hIconSmall;
+ winSelectIcons(pWin, &hIcon, &hIconSmall);
+ if (hIcon) SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
+ if (hIconSmall) SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall);
+#endif
+
+ /* Change style back to popup, already placed... */
+ SetWindowLongPtr(hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+ SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
+ /* Adjust the X window to match the window placement we actually got... */
+ winAdjustXWindow(window, hWnd);
+
+ /* Make sure it gets the proper system menu for a WS_POPUP, too */
+ GetSystemMenu(hWnd, TRUE);
+
+ /* Establish the default style */
+ if (!xcwm_window_is_override_redirect(window))
+ {
+ if (parent)
+ {
+ /* Set the transient style flags */
+ SetWindowLongPtr(hWnd, GWL_STYLE, WS_POPUP | WS_OVERLAPPED | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+ }
+ else
+ {
+ /* Set the window standard style flags */
+ SetWindowLongPtr(hWnd, GWL_STYLE, (WS_POPUP | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS) & ~WS_CAPTION & ~WS_SIZEBOX);
+ }
+ }
+ else
+ {
+ /* override-redirect window, remains un-decorated, but put it on top of all other X windows */
+ /* zstyle = SWP_TOPMOST; */
+ }
+
+ /* Apply all properties which effect the window appearance or behaviour */
+ UpdateName(window);
+ /* UpdateIcon(); */
+#if 0
+ if (!xcwm_window_is_override_redirect(window))
+ UpdateStyle(window);
+#endif
+
+ BumpWindowPosition(hWnd);
+
+#if 0
+ /* Display the window without activating it */
+ if (attr->_class != XCB_WINDOW_CLASS_INPUT_ONLY)
+#endif
+ ShowWindow (hWnd, SW_SHOWNOACTIVATE);
+}
+
+void
+winDestroyWindowsWindow(xcwm_window_t *window)
+{
+ DEBUG("winDestroyWindowsWindow: window 0x%08x XID 0x%08x\n", window, window->window_id);
+
+ HWND hWnd = xcwm_window_get_local_data(window);
+
+ /* Bail out if the Windows window handle is invalid */
+ if (hWnd == NULL)
+ return;
+
+#if 0
+ /* Store the info we need to destroy after this window is gone */
+ hIcon = (HICON)SendMessage(pWin->hWnd, WM_GETICON, ICON_BIG, 0);
+ hIconSm = (HICON)SendMessage(pWin->hWnd, WM_GETICON, ICON_SMALL, 0);
+#endif
+
+ /* Destroy the Windows window */
+ DestroyWindow(hWnd);
+
+ /* Null our handle to the Window so referencing it will cause an error */
+ xcwm_window_set_local_data(window, NULL);
+
+#if 0
+ /* Destroy any icons we created for this window */
+ winDestroyIcon(hIcon);
+ winDestroyIcon(hIconSm);
+#endif
+}
diff --git a/src/winmessages.h b/src/winmessages.h
new file mode 100644
index 0000000..8b04277
--- /dev/null
+++ b/src/winmessages.h
@@ -0,0 +1,1054 @@
+/*
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef WINMESSAGES_H
+#define WINMESSAGES_H
+
+static const unsigned MESSAGE_NAMES_LEN = 1024;
+static const char *MESSAGE_NAMES[1024] = {
+ "WM_NULL",
+ "WM_CREATE",
+ "WM_DESTROY",
+ "WM_MOVE",
+ "4",
+ "WM_SIZE",
+ "WM_ACTIVATE",
+ "WM_SETFOCUS",
+ "WM_KILLFOCUS",
+ "9",
+ "WM_ENABLE",
+ "WM_SETREDRAW",
+ "WM_SETTEXT",
+ "WM_GETTEXT",
+ "WM_GETTEXTLENGTH",
+ "WM_PAINT",
+ "WM_CLOSE",
+ "WM_QUERYENDSESSION",
+ "WM_QUIT",
+ "WM_QUERYOPEN",
+ "WM_ERASEBKGND",
+ "WM_SYSCOLORCHANGE",
+ "WM_ENDSESSION",
+ "23",
+ "WM_SHOWWINDOW",
+ "25",
+ "WM_WININICHANGE",
+ "WM_DEVMODECHANGE",
+ "WM_ACTIVATEAPP",
+ "WM_FONTCHANGE",
+ "WM_TIMECHANGE",
+ "WM_CANCELMODE",
+ NULL /* WM_SETCURSOR */,
+ "WM_MOUSEACTIVATE",
+ "WM_CHILDACTIVATE",
+ "WM_QUEUESYNC",
+ "WM_GETMINMAXINFO",
+ "37",
+ "WM_PAINTICON",
+ "WM_ICONERASEBKGND",
+ "WM_NEXTDLGCTL",
+ "41",
+ "WM_SPOOLERSTATUS",
+ "WM_DRAWITEM",
+ "WM_MEASUREITEM",
+ "WM_DELETEITEM",
+ "WM_VKEYTOITEM",
+ "WM_CHARTOITEM",
+ "WM_SETFONT",
+ "WM_GETFONT",
+ "WM_SETHOTKEY",
+ "WM_GETHOTKEY",
+ "52",
+ "53",
+ "54",
+ "WM_QUERYDRAGICON",
+ "56",
+ "WM_COMPAREITEM",
+ "58",
+ "59",
+ "60",
+ "61",
+ "62",
+ "63",
+ "64",
+ "WM_COMPACTING",
+ "66",
+ "67",
+ "WM_COMMNOTIFY",
+ "69",
+ "WM_WINDOWPOSCHANGING",
+ "WM_WINDOWPOSCHANGED",
+ "WM_POWER",
+ "73",
+ "WM_COPYDATA",
+ "WM_CANCELJOURNAL",
+ "76",
+ "77",
+ "WM_NOTIFY",
+ "79",
+ "WM_INPUTLANGCHANGEREQUEST",
+ "WM_INPUTLANGCHANGE",
+ "WM_TCARD",
+ "WM_HELP",
+ "WM_USERCHANGED",
+ "WM_NOTIFYFORMAT",
+ "86",
+ "87",
+ "88",
+ "89",
+ "90",
+ "91",
+ "92",
+ "93",
+ "94",
+ "95",
+ "96",
+ "97",
+ "98",
+ "99",
+ "100",
+ "101",
+ "102",
+ "103",
+ "104",
+ "105",
+ "106",
+ "107",
+ "108",
+ "109",
+ "110",
+ "111",
+ "112",
+ "113",
+ "114",
+ "115",
+ "116",
+ "117",
+ "118",
+ "119",
+ "120",
+ "121",
+ "122",
+ "WM_CONTEXTMENU",
+ "WM_STYLECHANGING",
+ "WM_STYLECHANGED",
+ "WM_DISPLAYCHANGE",
+ "WM_GETICON",
+ "WM_SETICON",
+ "WM_NCCREATE",
+ "WM_NCDESTROY",
+ "WM_NCCALCSIZE",
+ NULL /* WM_NCHITTEST */,
+ "WM_NCPAINT",
+ "WM_NCACTIVATE",
+ "WM_GETDLGCODE",
+ "WM_SYNCPAINT",
+ "137",
+ "138",
+ "139",
+ "140",
+ "141",
+ "142",
+ "143",
+ "144",
+ "145",
+ "146",
+ "147",
+ "148",
+ "149",
+ "150",
+ "151",
+ "152",
+ "153",
+ "154",
+ "155",
+ "156",
+ "157",
+ "158",
+ "159",
+ NULL /* WM_NCMOUSEMOVE */,
+ "WM_NCLBUTTONDOWN",
+ "WM_NCLBUTTONUP",
+ "WM_NCLBUTTONDBLCLK",
+ "WM_NCRBUTTONDOWN",
+ "WM_NCRBUTTONUP",
+ "WM_NCRBUTTONDBLCLK",
+ "WM_NCMBUTTONDOWN",
+ "WM_NCMBUTTONUP",
+ "WM_NCMBUTTONDBLCLK",
+ "170",
+ "171",
+ "172",
+ "173",
+ "174",
+ "175",
+ "176",
+ "177",
+ "178",
+ "179",
+ "180",
+ "181",
+ "182",
+ "183",
+ "184",
+ "185",
+ "186",
+ "187",
+ "188",
+ "189",
+ "190",
+ "191",
+ "192",
+ "193",
+ "194",
+ "195",
+ "196",
+ "197",
+ "198",
+ "199",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "209",
+ "210",
+ "211",
+ "212",
+ "213",
+ "214",
+ "215",
+ "216",
+ "217",
+ "218",
+ "219",
+ "220",
+ "221",
+ "222",
+ "223",
+ "224",
+ "225",
+ "226",
+ "227",
+ "228",
+ "229",
+ "230",
+ "231",
+ "232",
+ "233",
+ "234",
+ "235",
+ "236",
+ "237",
+ "238",
+ "239",
+ "240",
+ "241",
+ "242",
+ "243",
+ "244",
+ "245",
+ "246",
+ "247",
+ "248",
+ "249",
+ "250",
+ "251",
+ "252",
+ "253",
+ "254",
+ "255",
+ "WM_KEYDOWN",
+ "WM_KEYUP",
+ "WM_CHAR",
+ "WM_DEADCHAR",
+ "WM_SYSKEYDOWN",
+ "WM_SYSKEYUP",
+ "WM_SYSCHAR",
+ "WM_SYSDEADCHAR",
+ "WM_CONVERTREQUESTEX",
+ "265",
+ "266",
+ "267",
+ "268",
+ "WM_IME_STARTCOMPOSITION",
+ "WM_IME_ENDCOMPOSITION",
+ "WM_IME_KEYLAST",
+ "WM_INITDIALOG",
+ "WM_COMMAND",
+ "WM_SYSCOMMAND",
+ NULL /* WM_TIMER */,
+ "WM_HSCROLL",
+ "WM_VSCROLL",
+ "WM_INITMENU",
+ "WM_INITMENUPOPUP",
+ "280",
+ "281",
+ "282",
+ "283",
+ "284",
+ "285",
+ "286",
+ "WM_MENUSELECT",
+ "WM_MENUCHAR",
+ "WM_ENTERIDLE",
+ "290",
+ "291",
+ "292",
+ "293",
+ "294",
+ "295",
+ "296",
+ "297",
+ "298",
+ "299",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "WM_CTLCOLORMSGBOX",
+ "WM_CTLCOLOREDIT",
+ "WM_CTLCOLORLISTBOX",
+ "WM_CTLCOLORBTN",
+ "WM_CTLCOLORDLG",
+ "WM_CTLCOLORSCROLLBAR",
+ "WM_CTLCOLORSTATIC",
+ "313",
+ "314",
+ "315",
+ "316",
+ "317",
+ "318",
+ "319",
+ "320",
+ "321",
+ "322",
+ "323",
+ "324",
+ "325",
+ "326",
+ "327",
+ "328",
+ "329",
+ "330",
+ "331",
+ "332",
+ "333",
+ "334",
+ "335",
+ "336",
+ "337",
+ "338",
+ "339",
+ "340",
+ "341",
+ "342",
+ "343",
+ "344",
+ "345",
+ "346",
+ "347",
+ "348",
+ "349",
+ "350",
+ "351",
+ "352",
+ "353",
+ "354",
+ "355",
+ "356",
+ "357",
+ "358",
+ "359",
+ "360",
+ "361",
+ "362",
+ "363",
+ "364",
+ "365",
+ "366",
+ "367",
+ "368",
+ "369",
+ "370",
+ "371",
+ "372",
+ "373",
+ "374",
+ "375",
+ "376",
+ "377",
+ "378",
+ "379",
+ "380",
+ "381",
+ "382",
+ "383",
+ "384",
+ "385",
+ "386",
+ "387",
+ "388",
+ "389",
+ "390",
+ "391",
+ "392",
+ "393",
+ "394",
+ "395",
+ "396",
+ "397",
+ "398",
+ "399",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "419",
+ "420",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "427",
+ "428",
+ "429",
+ "430",
+ "431",
+ "432",
+ "433",
+ "434",
+ "435",
+ "436",
+ "437",
+ "438",
+ "439",
+ "440",
+ "441",
+ "442",
+ "443",
+ "444",
+ "445",
+ "446",
+ "447",
+ "448",
+ "449",
+ "450",
+ "451",
+ "452",
+ "453",
+ "454",
+ "455",
+ "456",
+ "457",
+ "458",
+ "459",
+ "460",
+ "461",
+ "462",
+ "463",
+ "464",
+ "465",
+ "466",
+ "467",
+ "468",
+ "469",
+ "470",
+ "471",
+ "472",
+ "473",
+ "474",
+ "475",
+ "476",
+ "477",
+ "478",
+ "479",
+ "480",
+ "481",
+ "482",
+ "483",
+ "484",
+ "485",
+ "486",
+ "487",
+ "488",
+ "489",
+ "490",
+ "491",
+ "492",
+ "493",
+ "494",
+ "495",
+ "496",
+ "497",
+ "498",
+ "499",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "509",
+ "510",
+ "511",
+ NULL /* WM_MOUSEMOVE */,
+ "WM_LBUTTONDOWN",
+ "WM_LBUTTONUP",
+ "WM_LBUTTONDBLCLK",
+ "WM_RBUTTONDOWN",
+ "WM_RBUTTONUP",
+ "WM_RBUTTONDBLCLK",
+ "WM_MBUTTONDOWN",
+ "WM_MBUTTONUP",
+ "WM_MBUTTONDBLCLK",
+ "WM_MOUSEWHEEL",
+ "WM_XBUTTONDOWN",
+ "WM_XBUTTONUP",
+ "WM_XBUTTONDBLCLK",
+ "526",
+ "527",
+ "WM_PARENTNOTIFY",
+ "WM_ENTERMENULOOP",
+ "WM_EXITMENULOOP",
+ "WM_NEXTMENU",
+ "WM_SIZING",
+ "WM_CAPTURECHANGED",
+ "WM_MOVING",
+ "535",
+ "WM_POWERBROADCAST",
+ "WM_DEVICECHANGE",
+ "538",
+ "539",
+ "540",
+ "541",
+ "542",
+ "543",
+ "WM_MDICREATE",
+ "WM_MDIDESTROY",
+ "WM_MDIACTIVATE",
+ "WM_MDIRESTORE",
+ "WM_MDINEXT",
+ "WM_MDIMAXIMIZE",
+ "WM_MDITILE",
+ "WM_MDICASCADE",
+ "WM_MDIICONARRANGE",
+ "WM_MDIGETACTIVE",
+ "554",
+ "555",
+ "556",
+ "557",
+ "558",
+ "559",
+ "WM_MDISETMENU",
+ "WM_ENTERSIZEMOVE",
+ "WM_EXITSIZEMOVE",
+ "WM_DROPFILES",
+ "WM_MDIREFRESHMENU",
+ "565",
+ "566",
+ "567",
+ "568",
+ "569",
+ "570",
+ "571",
+ "572",
+ "573",
+ "574",
+ "575",
+ "576",
+ "577",
+ "578",
+ "579",
+ "580",
+ "581",
+ "582",
+ "583",
+ "584",
+ "585",
+ "586",
+ "587",
+ "588",
+ "589",
+ "590",
+ "591",
+ "592",
+ "593",
+ "594",
+ "595",
+ "596",
+ "597",
+ "598",
+ "599",
+ "600",
+ "601",
+ "602",
+ "603",
+ "604",
+ "605",
+ "606",
+ "607",
+ "608",
+ "609",
+ "610",
+ "611",
+ "612",
+ "613",
+ "614",
+ "615",
+ "616",
+ "617",
+ "618",
+ "619",
+ "620",
+ "621",
+ "622",
+ "623",
+ "624",
+ "625",
+ "626",
+ "627",
+ "628",
+ "629",
+ "630",
+ "631",
+ "632",
+ "633",
+ "634",
+ "635",
+ "636",
+ "637",
+ "638",
+ "639",
+ "640",
+ "WM_IME_SETCONTEXT",
+ "WM_IME_NOTIFY",
+ "WM_IME_CONTROL",
+ "WM_IME_COMPOSITIONFULL",
+ "WM_IME_SELECT",
+ "WM_IME_CHAR",
+ "647",
+ "648",
+ "649",
+ "650",
+ "651",
+ "652",
+ "653",
+ "654",
+ "655",
+ "WM_IME_KEYDOWN",
+ "WM_IME_KEYUP",
+ "658",
+ "659",
+ "660",
+ "661",
+ "662",
+ "663",
+ "664",
+ "665",
+ "666",
+ "667",
+ "668",
+ "669",
+ "670",
+ "671",
+ "672",
+ "WM_MOUSEHOVER",
+ "674",
+ "WM_MOUSELEAVE",
+ "676",
+ "677",
+ "678",
+ "679",
+ "680",
+ "681",
+ "682",
+ "683",
+ "684",
+ "685",
+ "686",
+ "687",
+ "688",
+ "689",
+ "690",
+ "691",
+ "692",
+ "693",
+ "694",
+ "695",
+ "696",
+ "697",
+ "698",
+ "699",
+ "700",
+ "701",
+ "702",
+ "703",
+ "704",
+ "705",
+ "706",
+ "707",
+ "708",
+ "709",
+ "710",
+ "711",
+ "712",
+ "713",
+ "714",
+ "715",
+ "716",
+ "717",
+ "718",
+ "719",
+ "720",
+ "721",
+ "722",
+ "723",
+ "724",
+ "725",
+ "726",
+ "727",
+ "728",
+ "729",
+ "730",
+ "731",
+ "732",
+ "733",
+ "734",
+ "735",
+ "736",
+ "737",
+ "738",
+ "739",
+ "740",
+ "741",
+ "742",
+ "743",
+ "744",
+ "745",
+ "746",
+ "747",
+ "748",
+ "749",
+ "750",
+ "751",
+ "752",
+ "753",
+ "754",
+ "755",
+ "756",
+ "757",
+ "758",
+ "759",
+ "760",
+ "761",
+ "762",
+ "763",
+ "764",
+ "765",
+ "766",
+ "767",
+ "WM_CUT",
+ "WM_COPY",
+ "WM_PASTE",
+ "WM_CLEAR",
+ "WM_UNDO",
+ "WM_RENDERFORMAT",
+ "WM_RENDERALLFORMATS",
+ "WM_DESTROYCLIPBOARD",
+ "WM_DRAWCLIPBOARD",
+ "WM_PAINTCLIPBOARD",
+ "WM_VSCROLLCLIPBOARD",
+ "WM_SIZECLIPBOARD",
+ "WM_ASKCBFORMATNAME",
+ "WM_CHANGECBCHAIN",
+ "WM_HSCROLLCLIPBOARD",
+ "WM_QUERYNEWPALETTE",
+ "WM_PALETTEISCHANGING",
+ "WM_PALETTECHANGED",
+ "WM_HOTKEY",
+ "787",
+ "788",
+ "789",
+ "790",
+ "WM_PRINT",
+ "WM_PRINTCLIENT",
+ "793",
+ "794",
+ "795",
+ "796",
+ "797",
+ "798",
+ "799",
+ "800",
+ "801",
+ "802",
+ "803",
+ "804",
+ "805",
+ "806",
+ "807",
+ "808",
+ "809",
+ "810",
+ "811",
+ "812",
+ "813",
+ "814",
+ "815",
+ "816",
+ "817",
+ "818",
+ "819",
+ "820",
+ "821",
+ "822",
+ "823",
+ "824",
+ "825",
+ "826",
+ "827",
+ "828",
+ "829",
+ "830",
+ "831",
+ "832",
+ "833",
+ "834",
+ "835",
+ "836",
+ "837",
+ "838",
+ "839",
+ "840",
+ "841",
+ "842",
+ "843",
+ "844",
+ "845",
+ "846",
+ "847",
+ "848",
+ "849",
+ "850",
+ "851",
+ "852",
+ "853",
+ "854",
+ "855",
+ "856",
+ "857",
+ "858",
+ "859",
+ "860",
+ "861",
+ "862",
+ "863",
+ "864",
+ "865",
+ "866",
+ "867",
+ "868",
+ "869",
+ "870",
+ "871",
+ "872",
+ "873",
+ "874",
+ "875",
+ "876",
+ "877",
+ "878",
+ "879",
+ "880",
+ "881",
+ "882",
+ "883",
+ "884",
+ "885",
+ "886",
+ "887",
+ "888",
+ "889",
+ "890",
+ "891",
+ "892",
+ "893",
+ "894",
+ "895",
+ "896",
+ "897",
+ "898",
+ "899",
+ "900",
+ "901",
+ "902",
+ "903",
+ "904",
+ "905",
+ "906",
+ "907",
+ "908",
+ "909",
+ "910",
+ "911",
+ "912",
+ "913",
+ "914",
+ "915",
+ "916",
+ "917",
+ "918",
+ "919",
+ "920",
+ "921",
+ "922",
+ "923",
+ "924",
+ "925",
+ "926",
+ "927",
+ "928",
+ "929",
+ "930",
+ "931",
+ "932",
+ "933",
+ "934",
+ "935",
+ "936",
+ "937",
+ "938",
+ "939",
+ "940",
+ "941",
+ "942",
+ "943",
+ "944",
+ "945",
+ "946",
+ "947",
+ "948",
+ "949",
+ "950",
+ "951",
+ "952",
+ "953",
+ "954",
+ "955",
+ "956",
+ "957",
+ "958",
+ "959",
+ "960",
+ "961",
+ "962",
+ "963",
+ "964",
+ "965",
+ "966",
+ "967",
+ "968",
+ "969",
+ "970",
+ "971",
+ "972",
+ "973",
+ "974",
+ "975",
+ "976",
+ "977",
+ "978",
+ "979",
+ "980",
+ "981",
+ "982",
+ "983",
+ "984",
+ "985",
+ "986",
+ "987",
+ "988",
+ "989",
+ "990",
+ "991",
+ "992",
+ "993",
+ "994",
+ "995",
+ "996",
+ "997",
+ "998",
+ "999",
+ "1000",
+ "1001",
+ "1002",
+ "1003",
+ "1004",
+ "1005",
+ "1006",
+ "1007",
+ "1008",
+ "1009",
+ "1010",
+ "1011",
+ "1012",
+ "1013",
+ "1014",
+ "1015",
+ "1016",
+ "1017",
+ "1018",
+ "1019",
+ "1020",
+ "1021",
+ "1022",
+ "1023"
+};
+
+#endif