]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Remove vmware-user from open-vm-tools.
authorVMware, Inc <>
Mon, 26 Jul 2010 19:13:53 +0000 (12:13 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Mon, 26 Jul 2010 19:13:53 +0000 (12:13 -0700)
This change does a little bit more than just remove the sources. It also
modifies the vmware-user-suid-wrapper so that it executes
"vmtoolsd -n vmusr" in open-vm-tools. The desktop file is also fixed to
execute the suid wrapper, which is the right thing to do.

Also remove locationsdb.c from open-vm-tools, since it's not used there.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
26 files changed:
open-vm-tools/Makefile.am
open-vm-tools/configure.ac
open-vm-tools/vmware-user-suid-wrapper/Makefile.am
open-vm-tools/vmware-user-suid-wrapper/locationsdb.c [deleted file]
open-vm-tools/vmware-user-suid-wrapper/main.c
open-vm-tools/vmware-user-suid-wrapper/wrapper-linux.c
open-vm-tools/vmware-user-suid-wrapper/wrapper.h
open-vm-tools/vmware-user/COPYING [deleted file]
open-vm-tools/vmware-user/Makefile.am [deleted file]
open-vm-tools/vmware-user/copyPaste.c [deleted file]
open-vm-tools/vmware-user/copyPasteDnDWrapper.cpp [deleted file]
open-vm-tools/vmware-user/copyPasteDnDWrapper.h [deleted file]
open-vm-tools/vmware-user/copyPasteUI.cpp [deleted file]
open-vm-tools/vmware-user/copyPasteUI.h [deleted file]
open-vm-tools/vmware-user/debugStdio.c [deleted file]
open-vm-tools/vmware-user/dnd.c [deleted file]
open-vm-tools/vmware-user/dndUI.cpp [deleted file]
open-vm-tools/vmware-user/dndUI.h [deleted file]
open-vm-tools/vmware-user/dragDetWnd.cpp [deleted file]
open-vm-tools/vmware-user/dragDetWnd.h [deleted file]
open-vm-tools/vmware-user/modconfig.c [deleted file]
open-vm-tools/vmware-user/notify.c [deleted file]
open-vm-tools/vmware-user/pointer.c [deleted file]
open-vm-tools/vmware-user/vmware-user.cpp [deleted file]
open-vm-tools/vmware-user/vmwareuserInt.h [deleted file]
open-vm-tools/vmware-user/vmwareuser_version.h [deleted file]

index 2389e786e0dfa2d2741aceffc276b2f0434bef14..b0cf55762ec363333adef32d702839d5236354ac 100644 (file)
 # that all of our macros are in the 'm4' subdirectory.
 ACLOCAL_AMFLAGS = -I m4
 
-# These subdirectories require X, and may be disabled using --without-x
-X11_SUBDIRS =
-X11_SUBDIRS += vmware-user
-X11_SUBDIRS += vmware-user-suid-wrapper
-
 SUBDIRS =
 SUBDIRS += lib
 SUBDIRS += libvmtools
 SUBDIRS += libhgfs
-if HAVE_X11
-   SUBDIRS += $(X11_SUBDIRS)
-endif
 SUBDIRS += hgfsclient
 if BUILD_HGFSMOUNTER
    SUBDIRS += hgfsmounter
@@ -44,6 +36,9 @@ SUBDIRS += rpctool
 SUBDIRS += scripts
 SUBDIRS += services
 SUBDIRS += toolbox
+if HAVE_X11
+   SUBDIRS += vmware-user-suid-wrapper
+endif
 if HAVE_FUSE
    SUBDIRS += vmblock-fuse
 endif
index 3f9bc1fb4722ac52943586eba0e5b4f946383450..d7dd098bb40cfb6fcdf4c50c34c55596d9123f24 100644 (file)
@@ -1278,7 +1278,6 @@ AC_CONFIG_FILES([                      \
    services/plugins/vix/Makefile       \
    services/plugins/vixUser/Makefile   \
    services/plugins/vmbackup/Makefile  \
-   vmware-user/Makefile                \
    vmware-user-suid-wrapper/Makefile   \
    toolbox/Makefile                    \
    hgfsclient/Makefile                 \
index 2a0c5fec2a568104bd062e9c74a755db916490ae..346ffe100bb4f202fb054d24a70071f75889847c 100644 (file)
 
 bin_PROGRAMS = vmware-user-suid-wrapper
 
-# We shouldn't impose on users' installation preferences, so just provide
-# a sane default and let them override it at configure or make time.
-VMWARE_USER_PATH = $(bindir)/vmware-user
-
 AM_CPPFLAGS =
-AM_CPPFLAGS += -DVMWARE_USER_PATH=\"$(VMWARE_USER_PATH)\"
+AM_CPPFLAGS += -DVMTOOLSD_PATH=\"$(bindir)/vmtoolsd\"
 
 vmware_user_suid_wrapper_SOURCES =
 vmware_user_suid_wrapper_SOURCES += main.c
diff --git a/open-vm-tools/vmware-user-suid-wrapper/locationsdb.c b/open-vm-tools/vmware-user-suid-wrapper/locationsdb.c
deleted file mode 100644 (file)
index 8059eb7..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-
-/*
- * locationsdb.c --
- *
- *    Provides the QueryLocationsDB routine for finding keys in the locations
- *    database.  Because our application is a setuid binary and we want to
- *    minimize risk, we retain the duplicated functionality here rather than
- *    link against lib/unixinstall.
- */
-
-#if !defined(sun) && !defined(__FreeBSD__) && !defined(linux)
-# error This program is not supported on your platform.
-#endif
-
-#include <sys/param.h>
-
-#include <fcntl.h>
-#include <string.h>
-#include <strings.h>
-
-#include "vm_basic_types.h"
-#include "wrapper.h"
-
-
-
-/*
- * Local data
- */
-
-/*
- * Mappings between queries and search strings
- */
-
-typedef struct Mapping {
-   const char *answer;          /* string to match for "answer FOO" */
-   const char *remove;          /* string to match for "remove_answer FOO" */
-   size_t answerSize;           /* size of answer buffer */
-   size_t removeSize;           /* size of remove buffer */
-} Mapping;
-
-/*
- * queryMappings between Selector => search strings.  Used by QueryLocationsDB.
- */
-
-#define ANSWER_LIBDIR   "answer LIBDIR"
-#define REMOVE_LIBDIR   "remove_answer LIBDIR"
-#define ANSWER_BINDIR   "answer BINDIR"
-#define REMOVE_BINDIR   "remove_answer BINDIR"
-
-static Mapping queryMappings[] = {
-   { ANSWER_LIBDIR, REMOVE_LIBDIR, sizeof ANSWER_LIBDIR, sizeof REMOVE_LIBDIR },
-   { ANSWER_BINDIR, REMOVE_BINDIR, sizeof ANSWER_BINDIR, sizeof REMOVE_BINDIR },
-   { 0, 0, 0, 0 }
-};
-
-
-/*
- * Global functions (definitions)
- */
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * QueryLocationsDB --
- *
- *    Based on the caller's Selector, determines the directory selected as
- *    "LIBDIR", "BINDIR", etc. when the Tools were last configured.
- *
- * Results:
- *    TRUE on success, FALSE on failure.  queryDir is filled in on success.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-QueryLocationsDB(const char *locations, // IN : path of locations database
-                 Selector selector,     // IN : DB query to search for
-                 char *queryDir,        // OUT: address to write dirname to
-                 size_t queryDirSize)   // IN : size of queryDir buffer
-{
-   FILE *file = NULL;
-   char buf[MAXPATHLEN];
-   Bool found = FALSE;
-   Mapping *map;
-
-   if (selector < 0 || selector >= QUERY_MAX) {
-      Error("Internal logic error.  This is a bug.");
-      return FALSE;
-   }
-
-   file = fopen(locations, "r");
-   if (!file) {
-      return FALSE;
-   }
-
-   map = &queryMappings[selector];
-
-   /*
-    * We need to inspect the entire locations database since there are both
-    * "answer"s and "remove_answer"s.  We want to provide the last answer that
-    * has not been removed.
-    */
-   while (fgets(buf, sizeof buf, file)) {
-      if (strncmp(buf, map->answer, map->answerSize - 1) == 0) {
-         char *newline;
-
-         strncpy(queryDir, buf + map->answerSize, queryDirSize);
-         if (queryDir[queryDirSize - 1] != '\0') {
-            found = FALSE;
-            continue;
-         }
-
-         /* Truncate the string at the newline character, if it's present. */
-         newline = strchr(queryDir, '\n');
-         if (newline && newline - queryDir < queryDirSize) {
-            *newline = '\0';
-         }
-
-         found = TRUE;
-      } else if (strncmp(buf, map->remove, map->removeSize - 1) == 0) {
-         found = FALSE;
-      }
-   }
-
-   fclose(file);
-   return found;
-}
index a34c784cec144623d5f9da3c5eebbcfddc5bcfb9..117be8ddb8333f6915f48fa2ba94b019b373d6b5 100644 (file)
@@ -430,7 +430,8 @@ StartVMwareUser(char *const envp[])
    int fd = -1;
    int ret;
    char path[MAXPATHLEN];
-   char *argv[4];
+   char *argv[6];
+   size_t idx = 0;
 
    if (!BuildExecPath(path, sizeof path)) {
       return FALSE;
@@ -480,25 +481,25 @@ StartVMwareUser(char *const envp[])
     * can't parse the descriptor to pass as an argument.  We set up the
     * argument vector accordingly.
     */
-   argv[0] = path;
+   argv[idx++] = path;
+   argv[idx++] = "-n";
+   argv[idx++] = "vmusr";
 
    if (fd < 0) {
       Error("could not open %s\n", VMBLOCK_DEVICE);
-      argv[1] = NULL;
    } else {
       char fdStr[8];
 
       ret = snprintf(fdStr, sizeof fdStr, "%d", fd);
       if (ret == 0 || ret >= sizeof fdStr) {
          Error("could not parse file descriptor (%d)\n", fd);
-         argv[1] = NULL;
       } else {
-         argv[1] = "--blockFd";
-         argv[2] = fdStr;
-         argv[3] = NULL;
+         argv[idx++] = "--blockFd";
+         argv[idx++] = fdStr;
       }
    }
 
+   argv[idx++] = NULL;
    CompatExec(path, argv, envp);
 
    /*
@@ -506,7 +507,7 @@ StartVMwareUser(char *const envp[])
     * if CompatExec fails.
     */
    Error("could not execute %s: %s\n", path, strerror(errno));
-   exit(EXIT_FAILURE);
+   _exit(EXIT_FAILURE);
 }
 
 
@@ -533,10 +534,10 @@ Bool
 BuildExecPath(char *execPath,           // OUT: Buffer to store executable's path
               size_t execPathSize)      // IN : size of execPath buffer
 {
-   if (execPathSize < sizeof VMWARE_USER_PATH) {
+   if (execPathSize < sizeof VMTOOLSD_PATH) {
       return FALSE;
    }
-   strcpy(execPath, VMWARE_USER_PATH);
+   strcpy(execPath, VMTOOLSD_PATH);
    return TRUE;
 }
 #endif // ifndef USES_LOCATIONS_DB
index bf7e2fee8adb2264ea32d8f87efb7125edfebaee..5b5d4788b6504d27fe902bc38693ed66ca54b3cc 100644 (file)
@@ -74,16 +74,16 @@ BuildExecPath(char *execPath,           // OUT: Buffer to store executable's pat
     * paths to all the other paths selected during Tools configuration.  The
     * locations database file is only writable by root, so we can trust it.
     */
-   if (!QueryLocationsDB(LOCATIONS_PATH, QUERY_BINDIR, tmpPath, sizeof tmpPath)) {
-      Error("could not obtain BINDIR\n");
+   if (!QueryLocationsDB(LOCATIONS_PATH, QUERY_SBINDIR, tmpPath, sizeof tmpPath)) {
+      Error("could not obtain SBINDIR\n");
       return FALSE;
    }
 
-   if (strlen(tmpPath) + strlen("/vmware-user-wrapper") + 1 > sizeof tmpPath) {
+   if (strlen(tmpPath) + strlen("/vmtoolsd") + 1 > sizeof tmpPath) {
       Error("could not construct program filename\n");
       return FALSE;
    }
-   strcat(tmpPath, "/vmware-user-wrapper");
+   strcat(tmpPath, "/vmtoolsd");
 
    /*
     * From readlink(2), "The readlink() system call does not append a NUL
index a6ed699956a38ef8ed96b11d8b1c1c8545c2e9ff..6335b99260e48f4e7ea541293bb596c896c3e788 100644 (file)
  */
 
 typedef enum {
-   QUERY_LIBDIR = 0,    /* Ask for "BINDIR" */
-   QUERY_BINDIR,        /* Ask for "LIBDIR" */
+   QUERY_LIBDIR = 0,    /* Ask for "LIBDIR" */
+   QUERY_BINDIR,        /* Ask for "BINDIR" */
+   QUERY_SBINDIR,       /* Ask for "SBINDIR" */
    QUERY_MAX            /* Upper limit -- Insert other queries above only. */
 } Selector;
 #else
-#   ifndef VMWARE_USER_PATH
-#      error This program requires either USES_LOCATIONS_DB or VMWARE_USER_PATH.
-#   endif // ifndef VMWARE_USER_PATH
+#   ifndef VMTOOLSD_PATH
+#      error This program requires either USES_LOCATIONS_DB or VMTOOLSD_PATH.
+#   endif // ifndef VMTOOLSD_PATH
 #endif // ifdef USES_LOCATIONS_DB
 
 
diff --git a/open-vm-tools/vmware-user/COPYING b/open-vm-tools/vmware-user/COPYING
deleted file mode 100644 (file)
index 09f465a..0000000
+++ /dev/null
@@ -1,502 +0,0 @@
-                 GNU LESSER GENERAL PUBLIC LICENSE
-                      Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 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.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-                           Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-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 and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
-                 GNU LESSER GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, 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 library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete 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 distribute a copy of this License along with the
-Library.
-
-  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 Library or any portion
-of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-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 Library, 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 Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you 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.
-
-  If distribution of 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 satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be 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.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library 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.
-
-  9. 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 Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-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 with
-this License.
-
-  11. 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 Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library 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 Library.
-
-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.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library 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.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser 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 Library
-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 Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-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
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "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
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. 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 LIBRARY 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
-LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  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 library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
diff --git a/open-vm-tools/vmware-user/Makefile.am b/open-vm-tools/vmware-user/Makefile.am
deleted file mode 100644 (file)
index 484de3f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-################################################################################
-### Copyright 2007 VMware, Inc.  All rights reserved.
-###
-### This program is free software; you can redistribute it and/or modify
-### it under the terms of version 2 of the GNU General Public License as
-### published by the Free Software Foundation.
-###
-### 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 St, Fifth Floor, Boston, MA  02110-1301  USA
-################################################################################
-
-bin_PROGRAMS = vmware-user
-
-AM_CFLAGS =
-
-AM_CXXFLAGS = $(AM_CFLAGS)
-
-vmware_user_SOURCES =
-vmware_user_SOURCES += vmware-user.cpp
-
-install-exec-hook:
-       $(INSTALL) -d $(DESTDIR)$(datadir)/applications/
-       $(INSTALL) -m 644 $(top_srcdir)/scripts/common/vmware-user.desktop \
-               $(DESTDIR)$(datadir)/applications/
-uninstall-hook:
-       rm -f $(DESTDIR)$(datadir)/applications/vmware-user.desktop
diff --git a/open-vm-tools/vmware-user/copyPaste.c b/open-vm-tools/vmware-user/copyPaste.c
deleted file mode 100644 (file)
index 12b1716..0000000
+++ /dev/null
@@ -1,2102 +0,0 @@
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * copyPaste.c --
- *
- *    Set of functions in guest side for copy/paste (both file and text).
- *    Currently there are 2 versions copy/paste. Version 1 only supports
- *    text copy/paste, and based on backdoor cmd. Version 2 supports both
- *    text and file copy/paste, and based on guestRPC.
- *
- *    G->H Text Copy/Paste (version 1)
- *    --------------------
- *    When Ungrab, CopyPaste_RequestSelection got called, which try to get
- *    selection text and send to backdoor.
- *
- *    H->G Text Copy/Paste (version 1)
- *    --------------------
- *    When grab, CopyPaste_GetBackdoorSelections got called, which first
- *    get host selection text, then claim as selection owner. If some app
- *    asks for selection, CopyPasteSelectionGetCB will reply with host
- *    selection text.
- *
- *    G->H Copy/Paste (version 2)
- *    --------------------
- *    When Ungrab, host vmx will send out rpc command "copypaste.gh.data.get",
- *    which handler is CopyPasteRpcInGHSetDataCB. It first tries to get selection
- *    contents and sends it back as rpc result. For file transfer, host vmx
- *    will transfer files with hgFileCopy lib. Function CopyPasteGHFileListGetNext
- *    will handle the file list during transfer.
- *
- *    H->G Copy/Paste (version 2)
- *    --------------------
- *    When grab, host vmx will send host selection content to guest with
- *    out rpc command "copypaste.hg.data.set", which handler is
- *    CopyPasteRpcInHGSetDataCB. It first keeps a copy then claim as selection
- *    owner. If some app asks for files, CopyPasteSelectionGetCB will ask host
- *    vmx to transfer files into a temp dir with rpc "copypaste.hgCopyFiles",
- *    then reply with host selection file list. For KDE and gnome the file list
- *    format is different. If someapp asks for text, CopyPasteSelectionGetCB
- *    will provide the data.
- */
-
-#include "vmwareuserInt.h"
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "vm_assert.h"
-#include "debug.h"
-#include "str.h"
-#include "strutil.h"
-#include "eventManager.h"
-#include "guestApp.h"
-#include "dnd.h"
-#include "util.h"
-#include "cpName.h"
-#include "cpNameUtil.h"
-#include "guestInfoLib.h"
-#include "vmblock.h"
-#include "file.h"
-#include "codeset.h"
-#include "escape.h"
-#include "hostinfo.h"
-#include "wiper.h"
-#include "vmware/guestrpc/tclodefs.h"
-
-/*
- * Gtk 1.2 doesn't know about the CLIPBOARD selection, but that doesn't matter, we
- * just create the atom we need directly in main().
- */
-#ifndef GDK_SELECTION_CLIPBOARD
-GdkAtom GDK_SELECTION_CLIPBOARD;
-#endif
-
-#ifndef GDK_SELECTION_TYPE_TIMESTAMP
-GdkAtom GDK_SELECTION_TYPE_TIMESTAMP;
-#endif
-
-#ifndef GDK_SELECTION_TYPE_UTF8_STRING
-GdkAtom GDK_SELECTION_TYPE_UTF8_STRING;
-#endif
-
-typedef struct FCPGHState {
-   char *fileList;
-   char *fileListNext;
-   size_t fileListSize;
-} FCPGHState;
-
-/*
- * Currently there are 2 versions copy/paste.
- * Key points in copy/paste version 1:
- * 1. Only text copy/paste
- * 2. copy/paste is based on backdoor directly
- *
- * Key points in copy/paste version 2:
- * 1. Support both file/text copy/paste
- * 2. Both file/text copy/paste are based on guestRPC
- */
-static int32 gVmxCopyPasteVersion = 1;
-
-/*
- * Getting a selection is an asyncronous event, so we have to keep track of both
- * selections globablly in order to decide which one to use.
- */
-static Bool gWaitingOnGuestSelection = FALSE;
-static char gGuestSelPrimaryBuf[MAX_SELECTION_BUFFER_LENGTH];
-static char gGuestSelClipboardBuf[MAX_SELECTION_BUFFER_LENGTH];
-static uint64 gGuestSelPrimaryTime = 0;
-static uint64 gGuestSelClipboardTime = 0;
-static char gHostClipboardBuf[MAX_SELECTION_BUFFER_LENGTH];
-
-/* Guest->Host state. */
-FCPGHState gFcpGHState;
-/* RPC buffer for Guest->Host FCP. */
-static char *gGHFCPRpcResultBuffer;
-/* File list size for Guest->Host FCP. */
-static size_t gGHFCPListSize;
-static Bool gHGFCPPending;
-/* Current selection is text or file list (for FCP). */
-static Bool gHGIsClipboardFCP;
-/* 
- * Total file size in selection list. This is used to check if there is enough
- * space in guest OS for host->guest file transfer.
- */
-static uint64 gHGFCPTotalSize;
-
-static GdkAtom gFCPAtom[NR_FCP_TARGETS];
-
-/* Host->guest file transfer status, used for sync between transfer and paste. */
-int gHGFCPFileTransferStatus;
-
-static char gFileRoot[DND_MAX_PATH];
-static size_t gFileRootSize;
-static Bool gIsOwner;
-static VmTimeType gHGGetListTime;
-
-/*
- * Forward Declarations
- */
-static INLINE void CopyPasteStateInit(void);
-static void CopyPasteSelectionReceivedCB(GtkWidget *widget,
-                                         GtkSelectionData *selection_data,
-                                         gpointer data);
-static void CopyPasteSelectionGetCB(GtkWidget *widget,
-                                    GtkSelectionData *selection_data,
-                                    guint info,
-                                    guint time_stamp,
-                                    gpointer data);
-static gint CopyPasteSelectionClearCB(GtkWidget *widget,
-                                      GdkEventSelection *event,
-                                      gpointer data);
-
-static void CopyPasteSetBackdoorSelections(void);
-static Bool CopyPasteRpcInGHSetDataCB(char const **result, size_t *resultLen,
-                                      const char *name, const char *args,
-                                      size_t argsSize,void *clientData);
-static Bool CopyPasteRpcInHGSetDataCB(char const **result, size_t *resultLen,
-                                      const char *name, const char *args,
-                                      size_t argsSize,void *clientData);
-
-static INLINE void CopyPasteGHFileListClear(void);
-static INLINE void CopyPasteGHFileListSet(char *fileList, size_t fileListSize);
-
-/* This struct is only used by CopyPasteSelectionRemoveTarget. */
-struct SelectionTargetList {
-  GdkAtom selection;
-  GtkTargetList *list;
-};
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteSelectionRemoveTarget --
- *
- *      To remove a target from a selection target list. The reason to develop
- *      this function is that in gtk there is only gtk_selection_add_target to
- *      add supported target to selection list, but no function to remove one.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      If no more target, the selection list will be removed too.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteSelectionRemoveTarget(GtkWidget *widget,
-                               GdkAtom selection,
-                               GdkAtom target)
-{
-   const char *selection_handler_key = "gtk-selection-handlers";
-   struct SelectionTargetList *targetList;
-   GList *tempList;
-   GList *selectionLists;
-
-   /* Get selection list. */
-   selectionLists = gtk_object_get_data(GTK_OBJECT (widget), selection_handler_key);
-   tempList = selectionLists;
-   while (tempList) {
-      /* Enumerate the list to find the selection. */
-      targetList = tempList->data;
-      if (targetList->selection == selection) {
-         /* Remove target. */
-         gtk_target_list_remove(targetList->list, target);
-         /* If no more target, remove selection from list. */
-         if (!targetList->list->list) {
-            /* Free target list. */
-            gtk_target_list_unref(targetList->list);
-            g_free(targetList);
-            /* Remove and free selection node. */
-            selectionLists = g_list_remove_link(selectionLists, tempList);
-            g_list_free_1(tempList);
-         }
-         break;
-      }
-      tempList = tempList->next;
-   }
-   /* Put new selection list back. */
-   gtk_object_set_data (GTK_OBJECT (widget), selection_handler_key, selectionLists);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPaste_RequestSelection --
- *
- *      Request the guest's text clipboard (asynchronously), we'll give it to 
- *      the host when the request completes. For version 1 guest->host text
- *      copy/paste.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      The owner of the clipboard will get a request from our application.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPaste_RequestSelection(void)
-{
-   if (gVmxCopyPasteVersion > 1) {
-      return;
-   }
-
-   /*
-    * Ask for both the PRIMARY and CLIPBOARD selections.
-    */
-   gGuestSelPrimaryBuf[0] = '\0';
-   gGuestSelClipboardBuf[0] = '\0';
-
-   /* Only send out request if we are not the owner. */
-   if (!gIsOwner) {
-      /* Try to get utf8 text from primary and clipboard. */
-      gWaitingOnGuestSelection = TRUE;
-      gtk_selection_convert(gUserMainWidget,
-                            GDK_SELECTION_PRIMARY,
-                            GDK_SELECTION_TYPE_UTF8_STRING,
-                            GDK_CURRENT_TIME);
-      while (gWaitingOnGuestSelection) gtk_main_iteration();
-
-      gWaitingOnGuestSelection = TRUE;
-      gtk_selection_convert(gUserMainWidget,
-                            GDK_SELECTION_CLIPBOARD,
-                            GDK_SELECTION_TYPE_UTF8_STRING,
-                            GDK_CURRENT_TIME);
-      while (gWaitingOnGuestSelection) gtk_main_iteration();
-
-      if (gGuestSelPrimaryBuf[0] == '\0' && gGuestSelClipboardBuf[0] == '\0') {
-         /*
-          * If we cannot get utf8 text, try to get localized text from primary
-          * and clipboard.
-          */
-         gWaitingOnGuestSelection = TRUE;
-         gtk_selection_convert(gUserMainWidget,
-                               GDK_SELECTION_PRIMARY,
-                               GDK_SELECTION_TYPE_STRING,
-                               GDK_CURRENT_TIME);
-         while (gWaitingOnGuestSelection) gtk_main_iteration();
-
-         gWaitingOnGuestSelection = TRUE;
-         gtk_selection_convert(gUserMainWidget,
-                               GDK_SELECTION_CLIPBOARD,
-                               GDK_SELECTION_TYPE_STRING,
-                               GDK_CURRENT_TIME);
-         while (gWaitingOnGuestSelection) gtk_main_iteration();
-      }
-   }
-   /* Send text to host. */
-   Debug("CopyPaste_RequestSelection: Prim is [%s], Clip is [%s]\n",
-         gGuestSelPrimaryBuf, gGuestSelClipboardBuf);
-   CopyPasteSetBackdoorSelections();
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteSelectionReceivedCB --
- *
- *      Callback for the gtk signal "selection_recieved".
- *      Called because we previously requested a copy/paste selection and
- *      finally got results of that asynchronous operation. After some basic
- *      sanity checks, send the result (in selection_data) thru the backdoor 
- *      (version 1) or guestRPC (version 2) so the vmx can copy it to host
- *      clipboard.
- *
- *      We made several requests for selections, the string (actual data) and
- *      file list for each of PRIMARY and CLIPBOARD selections. So this funtion
- *      will get called several times, once for each request.
- *
- *      For guest->host copy/paste (both text and file).
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteSelectionReceivedCB(GtkWidget *widget,                // IN: unused
-                             GtkSelectionData *selection_data, // IN: requested data
-                             gpointer data)                    // IN: unused
-{
-   char *target;
-   char *utf8Str = NULL;
-   size_t len;
-   size_t aligned_len;
-
-   if ((widget == NULL) || (selection_data == NULL)) {
-      Debug("CopyPasteSelectionReceivedCB: Error, widget or selection_data is invalid\n");
-      goto exit;
-   }
-
-   if (selection_data->length < 0) {
-      Debug("CopyPasteSelectionReceivedCB: Error, length less than 0\n");
-      goto exit;
-   }
-
-   /* Try to get clipboard or selection timestamp. */
-   if (selection_data->target == GDK_SELECTION_TYPE_TIMESTAMP) {
-      if (selection_data->selection == GDK_SELECTION_PRIMARY) {
-         if (selection_data->length == 4) {
-            gGuestSelPrimaryTime = *(uint32 *)selection_data->data;
-            Debug("CopyPasteSelectionReceivedCB: Got pri time [%"FMT64"u]\n",
-                  gGuestSelPrimaryTime);
-         } else if (selection_data->length == 8) {
-            gGuestSelPrimaryTime = *(uint64 *)selection_data->data;
-            Debug("CopyPasteSelectionReceivedCB: Got pri time [%"FMT64"u]\n",
-                  gGuestSelPrimaryTime);
-         } else {
-            Debug("CopyPasteSelectionReceivedCB: Unknown pri time. Size %d\n",
-                  selection_data->length);
-         }
-      }
-      if (selection_data->selection == GDK_SELECTION_CLIPBOARD) {
-         if (selection_data->length == 4) {
-            gGuestSelClipboardTime = *(uint32 *)selection_data->data;
-            Debug("CopyPasteSelectionReceivedCB: Got clip time [%"FMT64"u]\n",
-                  gGuestSelClipboardTime);
-         } else if (selection_data->length == 8) {
-            gGuestSelClipboardTime = *(uint64 *)selection_data->data;
-            Debug("CopyPasteSelectionReceivedCB: Got clip time [%"FMT64"u]\n",
-                  gGuestSelClipboardTime);
-         } else {
-            Debug("CopyPasteSelectionReceivedCB: Unknown clip time. Size %d\n",
-                  selection_data->length);
-         }
-      }
-      goto exit;
-   }
-
-   if (selection_data->selection == GDK_SELECTION_PRIMARY) {
-      target = gGuestSelPrimaryBuf;
-   } else if (selection_data->selection == GDK_SELECTION_CLIPBOARD) {
-      target = gGuestSelClipboardBuf;
-   } else {
-      goto exit;
-   }
-
-   utf8Str = selection_data->data;
-   len = strlen(selection_data->data);
-
-   if (selection_data->target != GDK_SELECTION_TYPE_STRING &&
-       selection_data->target != GDK_SELECTION_TYPE_UTF8_STRING) {
-      /* It is a file list. */
-      if (len >= MAX_SELECTION_BUFFER_LENGTH - 1) {
-         Warning("CopyPasteSelectionReceivedCB file list too long\n");
-      } else {
-         memcpy(target, selection_data->data, len + 1);
-      }
-      goto exit;
-   }
-
-   /*
-    * If target is GDK_SELECTION_TYPE_STRING, assume encoding is local code
-    * set. Convert to utf8 before send to vmx.
-    */
-   if (selection_data->target == GDK_SELECTION_TYPE_STRING &&
-       !CodeSet_CurrentToUtf8(selection_data->data,
-                              selection_data->length,
-                              &utf8Str,
-                              &len)) {
-      Debug("CopyPasteSelectionReceivedCB: Couldn't convert to utf8 code set\n");
-      gWaitingOnGuestSelection = FALSE;
-      return;
-   }
-
-   /*
-    * String in backdoor communication is 4 bytes by 4 bytes, so the len
-    * should be aligned to 4;
-    */
-   aligned_len = (len + 4) & ~3;
-   if (aligned_len >= MAX_SELECTION_BUFFER_LENGTH) {
-      /* With alignment, len is still possible to be less than max. */
-      if (len < (MAX_SELECTION_BUFFER_LENGTH - 1)) {
-         memcpy(target, utf8Str, len + 1);
-      } else {
-         memcpy(target, utf8Str, MAX_SELECTION_BUFFER_LENGTH - 1);
-         target[MAX_SELECTION_BUFFER_LENGTH - 1] ='\0';
-      }
-   } else {
-      memcpy(target, utf8Str, len + 1);
-   }
-
-exit:
-   if (selection_data->target == GDK_SELECTION_TYPE_STRING) {
-      free(utf8Str);
-   }
-   gWaitingOnGuestSelection = FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteSelectionGetCB --
- *
- *      Callback for the gtk signal "selection_get".
- *      This is called when some other app requests the copy/paste selection,
- *      probably because we declare oursleves the selection owner on mouse
- *      grab. In text copy/paste case, we simply respond with contents of 
- *      gHostClipboardBuf, which should have been set on mouse grab. In file
- *      copy/paste case, send file transfer request to host vmx, then return
- *      file list with right format according to different request.
- *      For host->guest copy/paste (both text and file).
- *
- * Results:
- *      None
- *
- * Side effects:
- *      An X message is sent to the requesting app containing the data, it
- *      will likely act on it in some way. In FCP case, may first start a 
- *      host->guest file transfer. Add block if blocking driver is available,
- *      otherwise wait till file copy done.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteSelectionGetCB(GtkWidget        *widget,         // IN: unused
-                        GtkSelectionData *selection_data, // IN: requested type
-                                                          // OUT:the data to be sent
-                        guint            info,            // IN: unused
-                        guint            time_stamp,      // IN: unsued
-                        gpointer         data)            // IN: unused
-{
-   const char *begin = NULL;
-   const char *end = NULL;
-   const char *next = NULL;
-   const char *pre = NULL;
-   const char *post = NULL;
-   size_t preLen = 0;
-   size_t postLen = 0;
-   int len = 0;
-   char *text = NULL;
-   size_t textLen = 1;
-   Bool blockAdded = FALSE;
-   Bool gnomeFCP = FALSE;
-   VmTimeType curTime;
-
-   if ((widget == NULL) || (selection_data == NULL)) {
-      Debug("CopyPasteSelectionGetCB: Error, widget or selection_data is invalid\n");
-      return;
-   }
-
-   /* If it is text copy paste, return gHostClipboardBuf. */
-   if (GDK_SELECTION_TYPE_STRING == selection_data->target ||
-       GDK_SELECTION_TYPE_UTF8_STRING == selection_data->target) {
-      char *outBuf = gHostClipboardBuf;
-      size_t len = strlen(gHostClipboardBuf);
-
-      /*
-       * If target is GDK_SELECTION_TYPE_STRING, assume encoding is local code
-       * set. Convert from utf8 to local one.
-       */
-      if (GDK_SELECTION_TYPE_STRING == selection_data->target &&
-          !CodeSet_Utf8ToCurrent(gHostClipboardBuf,
-                                 strlen(gHostClipboardBuf),
-                                 &outBuf,
-                                 &len)) {
-         Debug("CopyPasteSelectionGetCB: can not convert to current codeset\n");
-         return;
-      }
-
-      gtk_selection_data_set(selection_data, selection_data->target, 8,
-                             outBuf, len);
-      Debug("CopyPasteSelectionGetCB: Set text [%s]\n", outBuf);
-
-      if (GDK_SELECTION_TYPE_STRING == selection_data->target) {
-         free(outBuf);
-      }
-
-      return;
-   }
-   
-   if (selection_data->target != gFCPAtom[FCP_TARGET_INFO_URI_LIST] &&
-       selection_data->target != gFCPAtom[FCP_TARGET_INFO_GNOME_COPIED_FILES]) {
-      Debug("CopyPasteSelectionGetCB: Got unknown target\n");
-      return;
-   }
-
-   if (!gHGIsClipboardFCP) {
-      Debug("CopyPasteSelectionGetCB: no file list available\n");
-      return;
-   }
-
-   /*
-    * KDE may ask for clipboard content right after clipboard owner changed,
-    * and cause unexpected HG file copy. So HG FCP will return nothing for 1
-    * second after switch from host OS to guest OS. Please refer to bug 301971.
-    */
-   Hostinfo_GetTimeOfDay(&curTime);
-   if (curTime - gHGGetListTime < FCP_COPY_DELAY) {
-      Debug("%s: waiting for delay\n", __FUNCTION__);
-      return;
-   }
-
-   if (gHGFCPFileTransferStatus == FCP_FILE_TRANSFER_NOT_YET) {
-      if (GuestInfo_GetAvailableDiskSpace(gFileRoot) < gHGFCPTotalSize) {
-         Debug("CopyPasteSelectionGetCB no enough space to copy file from host.\n");
-         return;
-      }
-      /* Send host a rpc to start file transfer. */
-      if (!GuestApp_RpcSendOneCPName("copypaste.hg.copy.files", ' ',
-                                     gFileRoot, gFileRootSize)) {
-         Debug("CopyPasteSelectionGetCB: failed sending copypaste.hg.copy.files "
-               "with CPName");
-         return;
-      }
-      gHGFCPFileTransferStatus = FCP_FILE_TRANSFERRING;
-   }
-
-   if (DnD_BlockIsReady(&gBlockCtrl)) {
-      /* Add a block on the staging directory for this command. */
-      if (gBlockCtrl.AddBlock(gBlockCtrl.fd, gFileRoot)) {
-         Debug("CopyPasteSelectionGetCB: add block [%s].\n", gFileRoot);
-         blockAdded = TRUE;
-      } else {
-         Warning("CopyPasteSelectionGetCB: Unable to add block [%s].\n", gFileRoot);
-      }
-   }
-
-   if (!blockAdded) {
-      /*
-       * If there is no blocking driver, wait here till file copy is done.
-       * 2 reasons to keep this:
-       * 1. If run vmware-user stand-alone as non-root, blocking driver can not
-       *    be opened. Debug purpose only.
-       * 2. Other platforms (Solaris, FreeBSD, etc) may also use this code, and there
-       *    is no blocking driver yet.
-       */
-      Debug("CopyPasteSelectionGetCB no blocking driver, waiting for "
-            "HG file copy done ...\n");
-      while (gHGFCPFileTransferStatus != FCP_FILE_TRANSFERRED) {
-         struct timeval tv;
-         int nr;
-
-         tv.tv_sec = 0;
-         nr = EventManager_ProcessNext(gEventQueue, (uint64 *)&tv.tv_usec);
-         if (nr != 1) {
-            Debug("CopyPasteSelectionGetCB unexpected end of loop: returned "
-                  "value is %d.\n", nr);
-            return;
-         }
-         if (select(0, NULL, NULL, NULL, &tv) == -1) {
-            Debug("CopyPasteSelectionGetCB error in select (%s).\n", 
-                  strerror(errno));
-            return;         
-         }
-      }
-
-      Debug("CopyPasteSelectionGetCB file transfer done!\n");
-   }
-
-   /* Setup the format string components */
-   if (selection_data->target == gFCPAtom[FCP_TARGET_INFO_URI_LIST]) {
-      Debug("CopyPasteSelectionGetCB Got uri_list request!\n");
-      pre = DND_URI_LIST_PRE_KDE;
-      preLen = sizeof DND_URI_LIST_PRE_KDE - 1;
-      post = DND_URI_LIST_POST;
-      postLen = sizeof DND_URI_LIST_POST - 1;
-   }
-   if (selection_data->target == gFCPAtom[FCP_TARGET_INFO_GNOME_COPIED_FILES]) {
-      Debug("CopyPasteSelectionGetCB Got gnome_copied request!\n");
-      pre = FCP_GNOME_LIST_PRE;
-      preLen = sizeof FCP_GNOME_LIST_PRE - 1;
-      post = FCP_GNOME_LIST_POST;
-      postLen = sizeof FCP_GNOME_LIST_POST - 1;
-      gnomeFCP = TRUE;
-
-      textLen += 5;
-      text = Util_SafeRealloc(text, textLen);
-      Str_Snprintf(text, 6, "copy\n");
-   }
-
-   if (!pre) {
-      Debug("CopyPasteSelectionGetCB: invalid drag target info\n");
-      return;
-   }
-
-
-   /*
-    * Set begin to first non-NUL character and end to last NUL character to
-    * prevent errors in calling CPName_GetComponent().
-    */
-   for(begin = gHostClipboardBuf; *begin == '\0'; begin++)
-      ;
-   end = CPNameUtil_Strrchr(gHostClipboardBuf, gGHFCPListSize + 1, '\0');
-   ASSERT(end);
-
-   /* Build up selection data */
-   while ((len = CPName_GetComponent(begin, end, &next)) != 0) {
-      const size_t origTextLen = textLen;
-      Bool freeBegin = FALSE;
-
-      if (len < 0) {
-         Debug("CopyPasteSelectionGetCB: error getting next component\n");
-         if (text) {
-            free(text);
-         }
-         return;
-      }
-
-      /*
-       * A URI list will expect the provided path to be escaped.  If we cannot
-       * escape the path for some reason we just use the unescaped version and
-       * hope that it works.
-       */
-      if (selection_data->target == gFCPAtom[FCP_TARGET_INFO_URI_LIST]) {
-         size_t newLen;
-         char *escapedComponent;
-         int escIndex;
-         int bytesToEsc[256] = { 0, };
-
-         /* We escape the following characters based on RFC 1630. */
-         bytesToEsc['#'] = 1;
-         bytesToEsc['?'] = 1;
-         bytesToEsc['*'] = 1;
-         bytesToEsc['!'] = 1;
-         bytesToEsc['%'] = 1;  /* Escape character */
-
-         /* Escape non-ASCII characters so we can pass UTF-8 filenames */
-         for (escIndex = 0x80; escIndex < 0x100; escIndex++) {
-            bytesToEsc[escIndex] = 1;
-         }
-
-         escapedComponent = Escape_Do('%', bytesToEsc, begin, len, &newLen);
-         if (escapedComponent) {
-            begin = escapedComponent;
-            len = newLen;
-            freeBegin = TRUE;
-         }
-      }
-
-      /*
-       * Append component.  NUL terminator was accounted for by initializing
-       * textLen to one above.
-       */
-      textLen += preLen + len + postLen;
-      text = Util_SafeRealloc(text, textLen);
-
-      /* 
-       * Bug 143147: Gnome FCP does not like the trailing newlines. We don't
-       * have this problem for targets that ask for URI lists. So we don't see
-       * this problem on:
-       * - KDE which asks for URI lists during FCP
-       * - DnD in both Gnome and KDE since they ask for URI lists.
-       *
-       * This is a problem only for Gnome FCP which expects a specially
-       * formatted 'copy' command string containing the file list which it then
-       * converts into a URI list internally.
-       */
-      Str_Snprintf(text + origTextLen - 1,
-                   textLen - origTextLen + 1,
-                   "%s%s%s", pre, begin, gnomeFCP && next == end ? "" : post);
-
-      if (freeBegin) {
-         free((void *)begin);
-      }
-
-      /* Iterate to next component */
-      begin = next;
-   }
-
-   /*
-    * Send out the data using the selection system. When sending a string, GTK will
-    * ensure that a null terminating byte is added to the end so we do not need to
-    * add it. GTK also copies the data so the original will never be modified.
-    */
-   Debug("CopyPasteSelectionGetCB: set file list [%s]\n", text);
-   gtk_selection_data_set(selection_data, selection_data->target,
-                          8, /* 8 bits per character. */
-                          text, textLen);
-   free(text);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteSelectionClearCB --
- *
- *      Callback for the gtk signal "selection_clear".
- *
- * Results:
- *      Always TRUE.
- *
- * Side effects:
- *      None
- *
- *-----------------------------------------------------------------------------
- */
-
-static gint
-CopyPasteSelectionClearCB(GtkWidget          *widget,         // IN: unused
-                          GdkEventSelection  *event,          // IN: unused
-                          gpointer           data)            // IN: unused
-{
-   Debug("CopyPasteSelectionClearCB got clear signal\n");
-   gIsOwner = FALSE;
-   return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteSetBackdoorSelections --
- *
- *      Set the clipboard one of two ways, the old way or the new way.
- *      The old way uses GuestApp_SetSel and there's only one selection.
- *      Set backdoor selection with either primary selection or clipboard.
- *      The primary selection is the first priority, then clipboard.
- *      If both unavailable, set backdoor selection length to be 0.
- *      This will be used by older VMXs or VMXs on Windows hosts (which
- *      has only one clipboard). Doing this gives us backwards
- *      compatibility.
- *
- *      The new way uses new sets both PRIMARY and CLIPBOARD. Newer Linux
- *      VMXs will use these rather than the above method and have the two
- *      selections set separately.
- *
- *      XXX: The "new way" doesn't exist yet, the vmx has no support for it.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      The VMX probably changes some string buffers.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteSetBackdoorSelections(void)
-{
-   uint32 const *p;
-   size_t len;
-   size_t aligned_len;
-   size_t primaryLen;
-   size_t clipboardLen;
-   unsigned int i;
-
-   primaryLen = strlen(gGuestSelPrimaryBuf);
-   clipboardLen = strlen(gGuestSelClipboardBuf);
-
-   if (primaryLen) {
-      /*
-       * Send primary selection to backdoor if it exists.
-       */
-      p = (uint32 const *)gGuestSelPrimaryBuf;
-   } else if (clipboardLen) {
-      /*
-       * Otherwise send clipboard to backdoor if it exists.
-       */
-      p = (uint32 const *)gGuestSelClipboardBuf;
-   } else {
-      /*
-       * Neither selection is set
-       */
-      p = NULL;
-   }
-
-   if (p == NULL) {
-      GuestApp_SetSelLength(0);
-      Debug("CopyPasteSetBackdoorSelections Set empty text.\n");
-   } else {
-      len = strlen((char *)p);
-      Debug("CopyPasteSetBackdoorSelections Set text [%s].\n", (char *)p);
-      aligned_len = (len + 4) & ~3;
-
-      /* Here long string should already be truncated. */
-      ASSERT(aligned_len <= MAX_SELECTION_BUFFER_LENGTH);
-
-      GuestApp_SetSelLength(len);
-      for (i = 0; i < len; i += 4, p++) {
-         GuestApp_SetNextPiece(*p);
-      }
-   }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPaste_GetBackdoorSelections --
- *
- *      Get the clipboard "the old way".
- *      The old way uses GuestApp_SetSel and there's only one selection.
- *      We don't have to do anything for the "new way", since the host
- *      will just push PRIMARY and/or CLIPBOARD when they are available
- *      on the host.
- *
- *      XXX: the "new way" isn't availble yet because the vmx doesn't
- *           implement separate clipboards. Even when it does this
- *           function will still exist for backward compatibility
- *
- * Results:
- *      TRUE if selection length>=0, FLASE otherwise.
- *
- * Side effects:
- *      This application becomes the selection owner for PRIMARY and/or
-        CLIPBOARD selections.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-CopyPaste_GetBackdoorSelections(void)
-{
-   int selLength;
-   int iAtom;
-
-   if (gVmxCopyPasteVersion > 1) {
-      return TRUE;
-   }
-
-   selLength = GuestApp_GetHostSelectionLen();
-   if (selLength < 0) {
-      return FALSE;
-   } else if (selLength > 0) {
-      memset(gHostClipboardBuf, 0, sizeof (gHostClipboardBuf));
-      GuestApp_GetHostSelection(selLength, gHostClipboardBuf);
-      Debug("CopyPaste_GetBackdoorSelections Get text [%s].\n", gHostClipboardBuf);
-      gtk_selection_owner_set(gUserMainWidget,
-                              GDK_SELECTION_CLIPBOARD,
-                              GDK_CURRENT_TIME);
-      gtk_selection_owner_set(gUserMainWidget,
-                              GDK_SELECTION_PRIMARY,
-                              GDK_CURRENT_TIME);
-      gIsOwner = TRUE;
-      gHGIsClipboardFCP = FALSE;
-      for (iAtom = 0; iAtom < NR_FCP_TARGETS; iAtom++) {
-         CopyPasteSelectionRemoveTarget(gUserMainWidget,
-                                        GDK_SELECTION_PRIMARY,
-                                        gFCPAtom[iAtom]);
-         CopyPasteSelectionRemoveTarget(gUserMainWidget,
-                                        GDK_SELECTION_CLIPBOARD,
-                                        gFCPAtom[iAtom]);
-      }
-   }
-   return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteRpcInGHSetDataCB --
- *
- *    Handler function for the "copypaste.gh.data.get" RPC command. Host is
- *    asking for clipboard contents for guest->host copy/paste. If both primary
- *    selection and clipboard are empty, the empty list should also be sent back
- *    because Host should release clipboard owner.
- *
- *    For Guest->Host copy/paste operations only.
- *
- * Results:
- *    TRUE on success, FALSE on failure.
- *
- * Side effects:
- *    The owner of the clipboard will get requests from our application.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-CopyPasteRpcInGHSetDataCB(char const **result,  // OUT
-                          size_t *resultLen,    // OUT
-                          const char *name,     // IN
-                          const char *args,     // IN
-                          size_t argsSize,      // Ignored
-                          void *clientData)     // Ignored
-{
-   int iAtom;
-   GdkAtom activeSelection = GDK_SELECTION_PRIMARY;
-   char *source = gGuestSelPrimaryBuf;
-   char format[256];
-   char *rpcBody = NULL;
-   size_t rpcBodySize = 0;
-
-   gGuestSelPrimaryBuf[0] = '\0';
-   gGuestSelClipboardBuf[0] = '\0';
-
-   if (gIsOwner) {
-      Debug("CopyPasteRpcInGHSetDataCB Send empty buf to host\n");
-      return RpcIn_SetRetVals(result, resultLen, "", TRUE);
-   }
-
-   /* First check which one is newer, primary selection or clipboard. */
-   gGuestSelPrimaryTime = 0;
-   gGuestSelClipboardTime = 0;
-
-   gWaitingOnGuestSelection = TRUE;
-   gtk_selection_convert(gUserMainWidget,
-                         GDK_SELECTION_PRIMARY,
-                         GDK_SELECTION_TYPE_TIMESTAMP,
-                         GDK_CURRENT_TIME);
-   while (gWaitingOnGuestSelection) gtk_main_iteration();
-
-   gWaitingOnGuestSelection = TRUE;
-   gtk_selection_convert(gUserMainWidget,
-                         GDK_SELECTION_CLIPBOARD,
-                         GDK_SELECTION_TYPE_TIMESTAMP,
-                         GDK_CURRENT_TIME);
-   while (gWaitingOnGuestSelection) gtk_main_iteration();
-
-   if (gGuestSelPrimaryTime < gGuestSelClipboardTime) {
-      activeSelection = GDK_SELECTION_CLIPBOARD;
-      source = gGuestSelClipboardBuf;
-   }
-
-try_again:
-   /* Check if it is file list in the active selection. */
-   for (iAtom = 0; iAtom < NR_FCP_TARGETS; iAtom++) {
-      gWaitingOnGuestSelection = TRUE;
-      gtk_selection_convert(gUserMainWidget,
-                            activeSelection,
-                            gFCPAtom[iAtom],
-                            GDK_CURRENT_TIME);
-      while (gWaitingOnGuestSelection) gtk_main_iteration();
-      if (source[0] != '\0') {
-         if (gVmxCopyPasteVersion < 2) {
-            /* Only vmx version greater than 2 support file copy/paste. */
-            Debug("CopyPasteRpcInGHSetDataCB invalid operation\n");
-            return RpcIn_SetRetVals(result, resultLen,
-                                    "invalid operation", FALSE);
-         }
-         break;
-      }
-   }
-
-   if (source[0] != '\0') {
-      char *currName;
-      size_t currSize;
-      size_t index = 0;
-      char *ghFileList = NULL;
-      size_t ghFileListSize = 0;
-
-      /*
-       * In gnome, before file list there may be a extra line indicating it
-       * is a copy or cut.
-       */
-      if (strncmp(source, "copy", 4) == 0) {
-         source += 4;
-      }
-      if (strncmp(source, "cut", 3) == 0) {
-         source += 3;
-      }
-
-      while (*source == '\n' || *source == '\r' || *source == ' ') {
-         source++;
-      }
-
-      /*
-       * Get the the full filenames and last components from the URI list.  The
-       * body of the RPC message will be these last components delimited with
-       * NUL characters; the Guest->Host file list will be the full paths
-       * delimited by NUL characters.
-       */
-      while ((currName = DnD_UriListGetNextFile(source,
-                                                &index,
-                                                &currSize))) {
-         size_t lastComponentSize;
-         char *lastComponentStart;
-
-         /* Append current filename to Guest->Host list */
-         ghFileList = Util_SafeRealloc(ghFileList,
-                                       ghFileListSize + currSize + 1);
-         memcpy(ghFileList + ghFileListSize, currName, currSize);
-         ghFileListSize += currSize;
-         ghFileList[ghFileListSize] = '\0';
-         ghFileListSize++;
-
-         /* Append last component to RPC body */
-         lastComponentStart = CPNameUtil_Strrchr(currName, currSize, DIRSEPC);
-         if (!lastComponentStart) {
-            /*
-             * This shouldn't happen since filenames are absolute, but handle
-             * it as if the file name is the last component
-             */
-            lastComponentStart = currName;
-         } else {
-            /* Skip the last directory separator */
-            lastComponentStart++;
-         }
-
-         lastComponentSize = currName + currSize - lastComponentStart;
-         rpcBody = Util_SafeRealloc(rpcBody, rpcBodySize + lastComponentSize + 1);
-         memcpy(rpcBody + rpcBodySize, lastComponentStart, lastComponentSize);
-         rpcBodySize += lastComponentSize;
-         rpcBody[rpcBodySize] = '\0';
-         rpcBodySize++;
-
-         free(currName);
-      }
-
-      if (!ghFileList || !rpcBody) {
-         Warning("CopyPasteRpcInGHSetDataCB: no filenames retrieved "
-                 "from URI list\n");
-         free(ghFileList);
-         free(rpcBody);
-         return RpcIn_SetRetVals(result, resultLen,
-                                 "error retrieving file name", FALSE);
-      }
-
-      /* Set the list of full paths */
-      CopyPasteGHFileListSet(ghFileList, ghFileListSize);
-
-      /* rpcBody (and its size) will always contain a trailing NUL character */
-      rpcBodySize--;
-      Debug("CopyPasteRpcInGHSetDataCB: Sending: [%s] (%zu)\n",
-            CPName_Print(rpcBody, rpcBodySize), rpcBodySize);
-
-      Str_Sprintf(format, sizeof format, "%d ", CPFORMAT_FILELIST);
-      *resultLen = rpcBodySize + strlen(format);
-
-      free(gGHFCPRpcResultBuffer);
-      gGHFCPRpcResultBuffer = Util_SafeCalloc(1, rpcBodySize + strlen(format));
-
-      memcpy(gGHFCPRpcResultBuffer, format, strlen(format));
-      memcpy(gGHFCPRpcResultBuffer + strlen(format), rpcBody, rpcBodySize);
-      free(rpcBody);
-      *result = gGHFCPRpcResultBuffer;
-      return TRUE;
-   } else {
-      /* Try to get utf8 text from active selection. */
-      gWaitingOnGuestSelection = TRUE;
-      gtk_selection_convert(gUserMainWidget,
-                            activeSelection,
-                            GDK_SELECTION_TYPE_UTF8_STRING,
-                            GDK_CURRENT_TIME);
-      while (gWaitingOnGuestSelection) gtk_main_iteration();
-
-      if (source[0] == '\0') {
-         /* Try to get text from active selection. */
-         gWaitingOnGuestSelection = TRUE;
-         gtk_selection_convert(gUserMainWidget,
-                              activeSelection,
-                              GDK_SELECTION_TYPE_STRING,
-                              GDK_CURRENT_TIME);
-         while (gWaitingOnGuestSelection) gtk_main_iteration();
-      }
-
-      /*
-       * With 'cut' operation OpenOffice will put data into clipboard but
-       * set same timestamp for both clipboard and primary selection.
-       * If primary timestamp is same as clipboard timestamp, we should try
-       * clipboard again if primary selection is empty. For details please
-       * refer to bug 300780.
-       */
-      if (source[0] == '\0' &&
-          gGuestSelPrimaryTime == gGuestSelClipboardTime &&
-          gGuestSelPrimaryTime != 0) {
-         gGuestSelPrimaryTime = 0;
-         gGuestSelClipboardTime = 0;
-         activeSelection = GDK_SELECTION_CLIPBOARD;
-         source = gGuestSelClipboardBuf;
-         goto try_again;
-      }
-
-      if (source[0] != '\0') {
-         free(gGHFCPRpcResultBuffer);
-
-         gGHFCPRpcResultBuffer =
-            Str_Asprintf(NULL, "%d %s", CPFORMAT_TEXT, source);
-
-         if (!gGHFCPRpcResultBuffer) {
-            Debug("CopyPasteRpcInGHSetDataCB failed to alloc memory.\n");
-            return RpcIn_SetRetVals(result, resultLen,
-                                    "error allocating memory", FALSE);
-         }
-
-         *result = gGHFCPRpcResultBuffer;
-         *resultLen = strlen(gGHFCPRpcResultBuffer);
-
-         Debug("CopyPasteRpcInGHSetDataCB creating text: %s\n", source);
-
-         return TRUE;
-      }
-      /* Neither file list nor text is available, send empty list back. */
-      Debug("CopyPasteRpcInGHSetDataCB Send empty buf to host\n");
-      return RpcIn_SetRetVals(result, resultLen, "", TRUE);
-   }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * CopyPasteRpcInGHFinishCB --
- *
- *    For Guest->Host operations only.
- *
- *    Invoked when host side of copyPaste operation has finished.
- *
- * Results:
- *    TRUE on success, FALSE on failure.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-CopyPasteRpcInGHFinishCB(char const **result,      // OUT
-                         size_t *resultLen,        // OUT
-                         const char *name,         // IN
-                         const char *args,         // IN
-                         size_t argsSize,          // Ignored
-                         void *clientData)         // IN
-{
-   char *effect = NULL;
-   unsigned int index = 0;
-
-   gFcpGHState.fileListNext = gFcpGHState.fileList;
-
-   effect = StrUtil_GetNextToken(&index, args, " ");
-   if (!effect) {
-      Warning("CopyPasteRpcInGHFinishCB: no drop effect provided\n");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "drop effect not provided", FALSE);
-   }
-
-   Debug("CopyPasteRpcInGHFinishCB got effect %s\n", effect);
-
-   free(effect);
-   return RpcIn_SetRetVals(result, resultLen, "", TRUE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * CopyPasteGHFileListClear --
- *
- *    Clears existing Guest->Host file list, releasing any used resources.
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE void
-CopyPasteGHFileListClear(void)
-{
-   Debug("CopyPasteGHFileListClear: clearing G->H file list\n");
-   if (gFcpGHState.fileList) {
-      free(gFcpGHState.fileList);
-      gFcpGHState.fileList = NULL;
-   }
-   gFcpGHState.fileListSize = 0;
-   gFcpGHState.fileListNext = NULL;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * CopyPasteGHFileListSet --
- *
- *    Sets the Guest->Host file list that is accessed through
- *    CopyPasteGHFileListGetNext().
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    Clears the existing Guest->Host file list if it exists.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE void
-CopyPasteGHFileListSet(char *fileList,      // IN: new Guest->Host file list
-                       size_t fileListSize) // IN: size of the provided list
-{
-   CopyPasteGHFileListClear();
-   gFcpGHState.fileList = fileList;
-   gFcpGHState.fileListSize = fileListSize;
-   gFcpGHState.fileListNext = fileList;
-
-   Debug("CopyPasteGHFileListSet: [%s] (%"FMTSZ"u)\n",
-         CPName_Print(gFcpGHState.fileList, gFcpGHState.fileListSize),
-         gFcpGHState.fileListSize);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * CopyPasteGHFileListGetNext --
- *
- *    Retrieves the next file in the Guest->Host file list.
- *
- *    Note that this function may only be called after calling
- *    CopyPasteGHFileListSet() and before calling CopyPasteGHFileListClear().
- *
- * Results:
- *    TRUE on success, FALSE on failure.  If TRUE is returned, fileName is
- *    given a pointer to the filename's location or NULL if there are no more
- *    files, and fileNameSize is given the length of fileName.
- *
- * Side effects:
- *    The fileListNext value of the Guest->Host global state is updated.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-CopyPasteGHFileListGetNext(char **fileName,       // OUT: fill with filename location
-                           size_t *fileNameSize)  // OUT: fill with filename length
-{
-   char const *end;
-   char const *next;
-   int len;
-
-   ASSERT(gFcpGHState.fileList);
-   ASSERT(gFcpGHState.fileListNext);
-   ASSERT(gFcpGHState.fileListSize > 0);
-
-   /* Ensure end is the last NUL character */
-   end = CPNameUtil_Strrchr(gFcpGHState.fileList,
-                            gFcpGHState.fileListSize,
-                            '\0');
-   ASSERT(end);
-
-   /* Get the length of this filename and a pointer to the next one */
-   len = CPName_GetComponent(gFcpGHState.fileListNext, end, &next);
-   if (len < 0) {
-      Warning("CopyPasteGHFileListGetNext: error retrieving next component\n");
-      return FALSE;
-   }
-
-   /* No more entries in the list */
-   if (len == 0) {
-      Debug("CopyPasteGHFileListGetNext: no more entries\n");
-      *fileName = NULL;
-      *fileNameSize = 0;
-      gFcpGHState.fileListNext = gFcpGHState.fileList;
-      return TRUE;
-   }
-
-   Debug("CopyPasteGHFileListGetNext: returning [%s] (%d)\n",
-         gFcpGHState.fileListNext, len);
-
-   *fileName = gFcpGHState.fileListNext;
-   *fileNameSize = len;
-   gFcpGHState.fileListNext = (char *)next;
-   return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteHGSetData --
- *
- *    Host is sending text for copy/paste.
- *
- *    RPC command format:
- *    1. Format
- *    2. Size of text
- *    3. If text size > 0, then followed by text, otherwise nothing
- *
- *    For Host->Guest operations only.
- *
- * Results:
- *    TRUE on success, FALSE otherwise.
- *
- * Side effects:
- *    None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-CopyPasteHGSetData(char const **result,     // OUT
-                   size_t *resultLen,       // OUT
-                   const char *args)        // IN
-{
-   char *format = NULL;
-   char *sSize = NULL;
-   uint32 textSize;
-   unsigned int index = 0;
-   Bool ret = FALSE;
-   int iAtom;
-
-   /* Parse value string. */
-   format = StrUtil_GetNextToken(&index, args, " ");
-   index++; /* Ignore leading space before data. */
-   sSize = StrUtil_GetNextToken(&index, args, " ");
-   index++;
-   if (!format || !sSize) {
-      Debug("CopyPasteHGSetData failed to parse format & size\n");
-      ret = RpcIn_SetRetVals(result, resultLen,
-                             "format and size is not completed", FALSE);
-      goto exit;
-   }
-
-   textSize = atoi(sSize);
-   gHostClipboardBuf[0] = '\0';
-
-   if (textSize > 0) {
-      if (textSize >= MAX_SELECTION_BUFFER_LENGTH) {
-         textSize = MAX_SELECTION_BUFFER_LENGTH - 1;
-      }
-      memcpy(gHostClipboardBuf, args + index, textSize);
-      gHostClipboardBuf[textSize] = '\0';
-      Debug("CopyPasteHGSetData: Set text [%s]\n", gHostClipboardBuf);
-   }
-      
-   gtk_selection_owner_set(gUserMainWidget,
-                           GDK_SELECTION_CLIPBOARD,
-                           GDK_CURRENT_TIME);
-   gtk_selection_owner_set(gUserMainWidget,
-                           GDK_SELECTION_PRIMARY,
-                           GDK_CURRENT_TIME);
-   gIsOwner = TRUE;
-   gHGIsClipboardFCP = FALSE;
-
-   /* We put text into selection, so remove file target types from list. */
-   for (iAtom = 0; iAtom < NR_FCP_TARGETS; iAtom++) {
-      CopyPasteSelectionRemoveTarget(gUserMainWidget,
-                                     GDK_SELECTION_PRIMARY,
-                                     gFCPAtom[iAtom]);
-      CopyPasteSelectionRemoveTarget(gUserMainWidget,
-                                     GDK_SELECTION_CLIPBOARD,
-                                     gFCPAtom[iAtom]);
-   }
-
-   ret = RpcIn_SetRetVals(result, resultLen, "", TRUE);
-
-exit:
-   free(format);
-   free(sSize);
-   return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteRpcInHGDataFinishCB --
- *
- *       For Host->Guest operations only.
- *       Host has finished transferring copyPaste data to the guest. We do any
- *       post H->G operation cleanup here, like picking a new file root.
- *
- * Results:
- *       TRUE on success, FALSE otherwise
- *
- * Side effects:
- *       Copied files will be deleted in error or cancel case.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-CopyPasteRpcInHGDataFinishCB(char const **result,   // OUT
-                             size_t *resultLen,     // OUT
-                             const char *name,      // IN
-                             const char *args,      // IN
-                             size_t argsSize,       // Ignored
-                             void *clientData)      // IN: pointer to mainWnd
-{
-   unsigned int index = 0;
-   char *state;
-
-   Debug("CopyPasteRpcInHGDataFinishCB received copypaste data finish\n");
-
-   state = StrUtil_GetNextToken(&index, args, " ");
-
-   if (!state) {
-      Debug("CopyPasteRpcInHGDataFinishCB failed to parse data state\n");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "must specify data finish state", FALSE);
-   }
-
-   if (strcmp(state, "success") != 0) {
-      Debug("CopyPasteRpcInHGDataFinishCB data transfer error\n");
-      /*
-       * Delete staging directory in error or cancel case, otherwise
-       * target application may still try to get copied files because
-       * the file list is provided right after adding block to staging
-       * directory.
-       */
-      File_DeleteDirectoryTree(gFileRoot);
-   }
-
-   free(state);
-
-   ASSERT(gHGFCPFileTransferStatus == FCP_FILE_TRANSFERRING);
-   gHGFCPFileTransferStatus = FCP_FILE_TRANSFERRED;
-
-   if (DnD_BlockIsReady(&gBlockCtrl) &&
-       !gBlockCtrl.RemoveBlock(gBlockCtrl.fd, gFileRoot)) {
-      Warning("CopyPasteRpcInHGDataFinishCB: Unable to remove block [%s].\n",
-              gFileRoot);
-   }
-
-   /* get new root dir for next FCP operation. */
-   gFileRootSize = DnD_GetNewFileRoot(gFileRoot, sizeof gFileRoot);
-
-   Debug("CopyPasteRpcInHGDataFinishCB create staging dir [%s]\n", gFileRoot);
-
-   return RpcIn_SetRetVals(result, resultLen, "", TRUE);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteHGSetFileList --
- *
- *    Host is sending file list for FCP (file copy/paste).
- *
- *    RPC command format:
- *    1. Format
- *    2. Total size of all files in the list
- *    3. Size of file list string
- *    4. If list size > 0, then followed by file list, otherwise nothing
- *
- *    For Host->Guest FCP operations only.
- *
- * Results:
- *    TRUE on success, FALSE on failure.
- *
- * Side effects:
- *    None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-CopyPasteHGSetFileList(char const **result,     // OUT
-                       size_t *resultLen,       // OUT
-                       const char *args)        // IN
-{
-   char *format = NULL;
-   char *data = NULL;
-   char *sListSize = NULL;
-   size_t listSize;
-   char *sTotalSize = NULL;
-   char *stagingDirName = NULL;
-   char mountDirName[DND_MAX_PATH];
-   unsigned int index = 0;
-   Bool ret = FALSE;
-   char *retStr;
-   int iAtom;
-   Bool usingDnDBlock;
-
-   gHGFCPFileTransferStatus = FCP_FILE_TRANSFER_NOT_YET;
-   /* Parse value string. */
-   format = StrUtil_GetNextToken(&index, args, " ");
-   index++; /* Ignore leading space before data. */
-   sTotalSize = StrUtil_GetNextToken(&index, args, " ");
-   index++;
-   sListSize = StrUtil_GetNextToken(&index, args, " ");
-   index++;
-   if (!format || !sTotalSize || !sListSize) {
-      Debug("CopyPasteHGSetFileList failed to parse format & size\n");
-      retStr = "format or size is not completed";
-      goto exit;
-   }
-
-   listSize = atoi(sListSize);
-   /* 
-    * Total file size in selection list. This is used to check if there is enough
-    * space in guest OS for host->guest file transfer.
-    */
-   gHGFCPTotalSize = atol(sTotalSize);
-
-   if (listSize <= 0) {
-      Debug("CopyPasteHGSetFileList: got empty list\n");
-      gHostClipboardBuf[0] = '\0';
-      retStr = "";
-      ret = TRUE;
-      goto exit;
-   }
-
-   /*
-    * XXX Should do code set convertion here from utf8 to current for file list,
-    * but right now should not do that. The reason is that the hgfs server
-    * always puts utf8 file name into guest, which is not right if local guest
-    * encoding is non-utf8. DnD has same problem.
-    */
-
-   data = (char *)Util_SafeCalloc(1, listSize + 1);
-   memcpy(data, args + index, listSize);
-   data[listSize] = '\0';
-
-   usingDnDBlock = DnD_BlockIsReady(&gBlockCtrl);
-   if (usingDnDBlock) {
-      /*
-       * Here we take the last component of the actual file root, which is
-       * a temporary directory for this DnD operation, and append it to the
-       * mount point for vmblock.  This is where we want the target application
-       * to access the file since it will enable vmblock to block that
-       * application's progress if necessary.
-       */
-      stagingDirName = DnD_GetLastDirName(gFileRoot);
-      if (!stagingDirName) {
-         Debug("CopyPasteHGSetFileList: error construct stagingDirName\n");
-         retStr = "error construct stagingDirName";
-         goto exit;
-      }
-      if (strlen(gBlockCtrl.blockRoot) +
-          (sizeof DIRSEPS - 1) * 2 + strlen(stagingDirName) >= sizeof mountDirName) {
-         Debug("CopyPasteHGSetFileList: directory name too large.\n");
-         retStr = "directory name too large";
-         goto exit;
-      }
-      Str_Sprintf(mountDirName, sizeof mountDirName,
-                  "%s" DIRSEPS "%s" DIRSEPS, gBlockCtrl.blockRoot, stagingDirName);
-   }
-
-   /* Add the file root to the relative paths received from host */
-   if (!DnD_PrependFileRoot(usingDnDBlock ? mountDirName : gFileRoot,
-                            &data, &listSize)) {
-      Debug("CopyPasteHGSetFileList: error prepending guest file root\n");
-      retStr = "error prepending file root";
-      goto exit;
-   }
-
-   if (listSize + 1 > sizeof gHostClipboardBuf) {
-      Debug("CopyPasteHGSetFileList: data too large\n");
-      retStr = "data too large";
-      goto exit;
-   }
-
-   memcpy(gHostClipboardBuf, data, listSize + 1);
-   gGHFCPListSize = listSize;
-   gHGIsClipboardFCP = TRUE;
-   Debug("CopyPasteHGSetFileList: get file list [%s] (%zu)\n",
-         CPName_Print(gHostClipboardBuf, gGHFCPListSize), gGHFCPListSize);
-
-   for (iAtom = 0; iAtom < NR_FCP_TARGETS; iAtom++) {
-      gtk_selection_add_target(gUserMainWidget, GDK_SELECTION_PRIMARY,
-                               gFCPAtom[iAtom], 0);
-      gtk_selection_add_target(gUserMainWidget, GDK_SELECTION_CLIPBOARD,
-                               gFCPAtom[iAtom], 0);
-   }
-
-   Debug("CopyPasteHGSetFileList: added targets\n");
-   gtk_selection_owner_set(gUserMainWidget,
-                           GDK_SELECTION_CLIPBOARD,
-                           GDK_CURRENT_TIME);
-   gtk_selection_owner_set(gUserMainWidget,
-                           GDK_SELECTION_PRIMARY,
-                           GDK_CURRENT_TIME);
-   gIsOwner = TRUE;
-
-   retStr = "";
-   ret = TRUE;
-
-exit:
-   free(format);
-   free(data);
-   free(sTotalSize);
-   free(sListSize);
-   free(stagingDirName);
-   Hostinfo_GetTimeOfDay(&gHGGetListTime);
-   return RpcIn_SetRetVals(result, resultLen, retStr, ret);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteRpcInHGSetDataCB --
- *
- *    Host is sending data for copy/paste. The data can be text, file list, etc.
- *
- *    For Host->Guest operations only.
- *
- * Results:
- *    TRUE if success, FALSE otherwise.
- *
- * Side effects:
- *    None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-CopyPasteRpcInHGSetDataCB(char const **result,  // OUT
-                          size_t *resultLen,    // OUT
-                          const char *name,     // IN
-                          const char *args,     // IN
-                          size_t argsSize,      // Ignored
-                          void *clientData)     // IN: ignored
-{
-   char *formatStr = NULL;
-   DND_CPFORMAT format;
-   Bool ret = FALSE;
-
-   unsigned int index = 0;
-
-   if (gHGFCPFileTransferStatus == FCP_FILE_TRANSFERRING) {
-      return RpcIn_SetRetVals(result, resultLen,
-                              "", TRUE);
-   }
-
-   /* Parse value string. */
-   formatStr = StrUtil_GetNextToken(&index, args, " ");
-   index++; /* Ignore leading space before data. */
-
-   if (!formatStr) {
-      Debug("CopyPasteTcloHGDataSet failed to parse format\n");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "format and size is not completed", FALSE);
-   }
-
-   format = (DND_CPFORMAT)atoi(formatStr);
-   free(formatStr);
-
-   switch (format) {
-   case CPFORMAT_TEXT:
-      ret = CopyPasteHGSetData(result, resultLen, args);
-      break;
-   case CPFORMAT_FILELIST:
-      /* Only vmx version greater than 2 support file copy/paste. */
-      if (gVmxCopyPasteVersion < 2) {
-         Debug("CopyPasteRpcInHGSetDataCB invalid operation\n");
-         return RpcIn_SetRetVals(result, resultLen,
-                                 "invalid operation", FALSE);
-      }
-      ret = CopyPasteHGSetFileList(result, resultLen, args);
-      break;
-   default:
-      Debug("CopyPasteTcloHGDataSet unknown format\n");
-      ret = RpcIn_SetRetVals(result, resultLen,
-                             "unknown format", FALSE);
-      break;
-   }
-
-   return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * CopyPasteRpcInGHGetNextFileCB --
- *
- *    For Guest->Host operations only.
- *
- *    Invoked when the host is compiling its list of files to copy from the
- *    guest.  Here we provide the path of the next file in our Guest->Host file
- *    list in guest path format (for display purposes) and CPName format (for
- *    file copy operation).
- *
- * Results:
- *    TRUE on success, FALSE on failure.
- *
- * Side effects:
- *    Iterator pointer within file list of GH state is iterated to next list
- *    entry (through call to CopyPasteGHFileListGetNext()).
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-CopyPasteRpcInGHGetNextFileCB(char const **result,      // OUT
-                              size_t *resultLen,        // OUT
-                              const char *name,         // IN
-                              const char *args,         // IN
-                              size_t argsSize,          // Ignored
-                              void *clientData)         // IN
-{
-   static char resultBuffer[DND_MAX_PATH];
-   char *fileName;
-   size_t fileNameSize;
-   uint32 cpNameSize;
-   Bool res;
-
-   /*
-    * Retrieve a pointer to the next filename and its size from the list stored
-    * in the G->H DnD state.  Note that fileName should not be free(3)d here
-    * since an additional copy is not allocated.
-    */
-   res = CopyPasteGHFileListGetNext(&fileName, &fileNameSize);
-
-   if (!res) {
-      Warning("CopyPasteRpcInGHGetNextFileCB: error retrieving file name\n");
-      return RpcIn_SetRetVals(result, resultLen, "error getting file", FALSE);
-   }
-
-   if (!fileName) {
-      /* There are no more files to send */
-      Debug("CopyPasteRpcInGHGetNextFileCB: reached end of Guest->Host file list\n");
-      return RpcIn_SetRetVals(result, resultLen, "|end|", TRUE);
-   }
-
-   if (fileNameSize + 1 + fileNameSize > sizeof resultBuffer) {
-      Warning("CopyPasteRpcInGHGetNextFileCB: filename too large (%"FMTSZ"u)\n", fileNameSize);
-      return RpcIn_SetRetVals(result, resultLen, "filename too large", FALSE);
-   }
-
-   /*
-    * Construct a reply message of the form:
-    * <file name in guest format><NUL><filename in CPName format>
-    */
-   memcpy(resultBuffer, fileName, fileNameSize);
-   resultBuffer[fileNameSize] = '\0';
-
-   cpNameSize = CPNameUtil_ConvertToRoot(fileName,
-                                         sizeof resultBuffer - (fileNameSize + 1),
-                                         resultBuffer + fileNameSize + 1);
-   if (cpNameSize < 0) {
-      Warning("CopyPasteRpcInGHGetNextFileCB: could not convert to CPName\n");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "error on CPName conversion", FALSE);
-   }
-
-   /* Set manually because RpcIn_SetRetVals() assumes no NUL characters */
-   *result = resultBuffer;
-   *resultLen = fileNameSize + 1 + cpNameSize;
-
-   Debug("CopyPasteRpcInGHGetNextFileCB: [%s] (%"FMTSZ"u)\n",
-         CPName_Print(*result, *resultLen), *resultLen);
-
-   return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPaste_GetVmxCopyPasteVersion --
- *
- *      Ask the vmx for it's copy/paste version.
- *
- * Results:
- *      The copy/paste version the vmx supports, 1 if the vmx doesn't know
- *      what we're talking about.
- *
- * Side effects:
- *      None
- *
- *-----------------------------------------------------------------------------
- */
-
-int32
-CopyPaste_GetVmxCopyPasteVersion(void)
-{
-   char *reply = NULL;
-   size_t replyLen;
-
-   Debug("%s: enter\n", __FUNCTION__);
-   if (!RpcOut_sendOne(&reply, &replyLen, "vmx.capability.copypaste_version")) {
-      Debug("CopyPaste_GetVmxCopyPasteVersion: could not get VMX copyPaste "
-            "version capability: %s\n", reply ? reply : "NULL");
-      gVmxCopyPasteVersion = 1;
-   } else {
-      gVmxCopyPasteVersion = atoi(reply);
-   }
-
-   free(reply);
-   Debug("CopyPaste_GetVmxCopyPasteVersion: got version %d\n", gVmxCopyPasteVersion);
-   return gVmxCopyPasteVersion;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPaste_RegisterCapability --
- *
- *      Register the "copypaste" capability. Sometimes this needs to be done
- *      separately from the rest of copy/paste registration, so we provide it
- *      separately here.
- *
- * Results:
- *      TRUE on success
- *      FALSE on failure
- *
- * Side effects:
- *      None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-CopyPaste_RegisterCapability(void)
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   /* Tell the VMX about the copyPaste version we support. */
-   if (!RpcOut_sendOne(NULL, NULL, "tools.capability.copypaste_version 2")) {
-      Debug("CopyPaste_RegisterCapability: could not set guest copypaste "
-            "version capability\n");
-      gVmxCopyPasteVersion = 1;
-      return FALSE;
-   }
-   Debug("CopyPaste_RegisterCapability: set copypaste version 2\n");
-   return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPaste_Register --
- *
- *      Setup callbacks, initialize.
- *
- * Results:
- *      Always TRUE.
- *
- * Side effects:
- *      None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-CopyPaste_Register(GtkWidget* mainWnd)
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   /* Text copy/paste initialization for all versions. */
-#ifndef GDK_SELECTION_CLIPBOARD
-   GDK_SELECTION_CLIPBOARD = gdk_atom_intern("CLIPBOARD", FALSE);
-#endif
-
-#ifndef GDK_SELECTION_TYPE_TIMESTAMP
-   GDK_SELECTION_TYPE_TIMESTAMP = gdk_atom_intern("TIMESTAMP", FALSE);
-#endif
-
-#ifndef GDK_SELECTION_TYPE_UTF8_STRING
-   GDK_SELECTION_TYPE_UTF8_STRING = gdk_atom_intern("UTF8_STRING", FALSE);
-#endif
-
-   gFCPAtom[FCP_TARGET_INFO_GNOME_COPIED_FILES] = 
-      gdk_atom_intern(FCP_TARGET_NAME_GNOME_COPIED_FILES, FALSE);
-   gFCPAtom[FCP_TARGET_INFO_URI_LIST] = 
-      gdk_atom_intern(FCP_TARGET_NAME_URI_LIST, FALSE);
-
-   /* 
-    * String is always in supported list. FCP atoms will dynamically be 
-    * added and removed.
-    */
-   gtk_selection_add_target(mainWnd, GDK_SELECTION_PRIMARY,
-                            GDK_SELECTION_TYPE_STRING, 0);
-   gtk_selection_add_target(mainWnd, GDK_SELECTION_CLIPBOARD,
-                            GDK_SELECTION_TYPE_STRING, 0);
-   gtk_selection_add_target(mainWnd, GDK_SELECTION_PRIMARY,
-                            GDK_SELECTION_TYPE_UTF8_STRING, 0);
-   gtk_selection_add_target(mainWnd, GDK_SELECTION_CLIPBOARD,
-                            GDK_SELECTION_TYPE_UTF8_STRING, 0);
-
-   gtk_signal_connect(GTK_OBJECT(mainWnd), "selection_received",
-                      GTK_SIGNAL_FUNC(CopyPasteSelectionReceivedCB), mainWnd);
-   gtk_signal_connect(GTK_OBJECT(mainWnd), "selection_get",
-                      GTK_SIGNAL_FUNC(CopyPasteSelectionGetCB), mainWnd);
-   gtk_signal_connect(GTK_OBJECT(mainWnd), "selection_clear_event",
-                      GTK_SIGNAL_FUNC(CopyPasteSelectionClearCB), mainWnd);
-
-   RpcIn_RegisterCallback(gRpcIn, "copypaste.hg.data.set",
-                          CopyPasteRpcInHGSetDataCB, NULL);
-   RpcIn_RegisterCallback(gRpcIn, "copypaste.hg.data.finish",
-                          CopyPasteRpcInHGDataFinishCB, NULL);
-   RpcIn_RegisterCallback(gRpcIn, "copypaste.gh.data.get",
-                          CopyPasteRpcInGHSetDataCB, NULL);
-   RpcIn_RegisterCallback(gRpcIn, "copypaste.gh.get.next.file",
-                          CopyPasteRpcInGHGetNextFileCB, NULL);
-   RpcIn_RegisterCallback(gRpcIn, "copypaste.gh.finish",
-                          CopyPasteRpcInGHFinishCB, NULL);
-
-   CopyPasteStateInit();
-   Wiper_Init(NULL);
-
-   return CopyPaste_RegisterCapability();
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPaste_Unregister --
- *
- *      Cleanup copy/paste related things.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      copy/paste is stopped, the rpc channel to the vmx is closed.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPaste_Unregister(GtkWidget* mainWnd)
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   gtk_signal_disconnect_by_func(GTK_OBJECT(mainWnd),
-                                 GTK_SIGNAL_FUNC(CopyPasteSelectionReceivedCB),
-                                 mainWnd);
-   gtk_signal_disconnect_by_func(GTK_OBJECT(mainWnd),
-                                 GTK_SIGNAL_FUNC(CopyPasteSelectionGetCB),
-                                 mainWnd);
-   gtk_signal_disconnect_by_func(GTK_OBJECT(mainWnd),
-                                 GTK_SIGNAL_FUNC(CopyPasteSelectionClearCB),
-                                 mainWnd);
-   RpcIn_UnregisterCallback(gRpcIn, "copypaste.hg.data.set");
-   RpcIn_UnregisterCallback(gRpcIn, "copypaste.hg.data.finish");
-   RpcIn_UnregisterCallback(gRpcIn, "copypaste.gh.data.get");
-   RpcIn_UnregisterCallback(gRpcIn, "copypaste.gh.get.next.file");
-   RpcIn_UnregisterCallback(gRpcIn, "copypaste.gh.finish");
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPaste_OnReset --
- *
- *    Handles reinitializing Copy Paste state on a reset.
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPaste_OnReset(void)
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   if (gHGFCPFileTransferStatus == FCP_FILE_TRANSFERRING) {
-      File_DeleteDirectoryTree(gFileRoot);
-      if (DnD_BlockIsReady(&gBlockCtrl) &&
-          !gBlockCtrl.RemoveBlock(gBlockCtrl.fd, gFileRoot)) {
-         Warning("CopyPasteRpcInHGDataFinishCB: Unable to remove block [%s].\n",
-                 gFileRoot);
-      }
-      gFileRootSize = DnD_GetNewFileRoot(gFileRoot, sizeof gFileRoot);
-   }
-
-   CopyPasteStateInit();
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * CopyPaste_InProgress --
- *
- *    Indicates whether a copy/paste data transfer is currently in progress.
- *
- * Results:
- *    TRUE if in progress, FALSE otherwise.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-CopyPaste_InProgress(void)
-{
-   /* XXX We currently have no way to determine if a G->H FCP is ongoing. */
-   return gHGFCPFileTransferStatus == FCP_FILE_TRANSFERRING;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * CopyPaste_IsRpcCPSupported --
- *
- *    Check if RPC copy/paste is supported by vmx or not.
- *
- * Results:
- *    TRUE if RPC copy/paste is supported, FALSE otherwise.
- *
- * Side effects:
- *    None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-CopyPaste_IsRpcCPSupported(void)
-{
-   return gVmxCopyPasteVersion > 1;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * CopyPasteStateInit --
- *
- *    Initalialize CopyPaste State.
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-CopyPasteStateInit(void)
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   gHostClipboardBuf[0] = '\0';
-   gGuestSelPrimaryBuf[0] = '\0';
-   gGuestSelClipboardBuf[0] = '\0';
-   gIsOwner = FALSE;
-   gGHFCPRpcResultBuffer = NULL;
-   gHGFCPPending = FALSE;
-   gHGFCPFileTransferStatus = FCP_FILE_TRANSFER_NOT_YET;
-
-   if (CopyPaste_GetVmxCopyPasteVersion() >= 2) {
-      /*
-       * Create staging directory for file copy/paste. This is for vmx with version 2
-       * or greater.
-       */
-      gFileRootSize = DnD_GetNewFileRoot(gFileRoot, sizeof gFileRoot);
-      Debug("%s: create file root [%s]\n", __FUNCTION__, gFileRoot);
-   }
-}
diff --git a/open-vm-tools/vmware-user/copyPasteDnDWrapper.cpp b/open-vm-tools/vmware-user/copyPasteDnDWrapper.cpp
deleted file mode 100644 (file)
index 65d64f8..0000000
+++ /dev/null
@@ -1,503 +0,0 @@
-/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/**
- * @file copyPasteDnDWrapper.cpp
- *
- * This singleton class implements a wrapper around various versions of
- * copy and paste and dnd protocols, and provides some convenience functions
- * that help to make VMwareUser a bit cleaner.
- */
-
-#include "copyPasteDnDWrapper.h"
-
-extern "C" {
-#include "vmwareuserInt.h"
-#include "debug.h"
-#include "dndGuest.h"
-#include "unity.h"
-}
-
-class DragDetWnd;
-
-/**
- * CopyPasteDnDWrapper is a singleton, here is a pointer to its only instance.
- */
-CopyPasteDnDWrapper *CopyPasteDnDWrapper::m_instance = 0;
-
-/**
- *
- * Get an instance of CopyPasteDnDWrapper, which is an application singleton.  
- *
- * @return a pointer to the singleton CopyPasteDnDWrapper object, or NULL if
- * for some reason it could not be allocated.
- */
-
-CopyPasteDnDWrapper *
-CopyPasteDnDWrapper::GetInstance()
-{
-   if (!m_instance) {
-      m_instance = new CopyPasteDnDWrapper;
-   }
-   return m_instance;
-}
-
-#if defined(HAVE_GTKMM)
-extern "C" {
-
-/**
- *
- * Enter or leave unity mode.
- *
- * @param[in] mode enter unity mode if TRUE, else leave.
- */
-
-void
-CopyPasteDnDWrapper_SetUnityMode(Bool mode)
-{
-   CopyPasteDnDWrapper *wrapper = CopyPasteDnDWrapper::GetInstance();
-
-   if (wrapper) {
-      wrapper->SetUnityMode(mode);
-   }
-}
-
-}
-#endif
-
-/**
- *
- * Constructor.
- */
-
-CopyPasteDnDWrapper::CopyPasteDnDWrapper() :
-#if defined(HAVE_GTKMM)
-   m_copyPasteUI(NULL),
-   m_dndUI(NULL),
-#endif
-   m_isCPRegistered(FALSE),
-   m_isDnDRegistered(FALSE),
-   m_userData(NULL),
-   m_cpVersion(-1),
-   m_dndVersion(-1),
-   m_isLegacy(false),
-   m_hgWnd(NULL),
-   m_ghWnd(NULL),
-   m_eventQueue(NULL)
-{
-}
-
-
-/**
- *
- * Destructor.
- */
-
-CopyPasteDnDWrapper::~CopyPasteDnDWrapper()
-{
-   if (IsCPRegistered()) {
-      UnregisterCP();
-   }
-   if (IsDnDRegistered()) {
-      UnregisterDnD();
-   }
-}
-
-
-/**
- *
- * Attach implementation-specific data (in reality, a GtkWidget * that is
- * needed by the legacy copy paste code. Going forward, any new protocol
- * versions should be implemented as classes, and should not need such a
- * crutch). 
- *
- * @param[in] userData  a GtkWidget created by VMwareUser and used by the
- * legacy copy and paste implementation.
- */
-
-void
-CopyPasteDnDWrapper::SetUserData(const void *userData)
-{
-   Debug("%s: enter %lx\n", __FUNCTION__, (unsigned long) userData);
-   m_userData = userData;
-}
-
-
-/**
- *
- * Set block fd.
- *
- * @param[in] blockFd blockFd specified as command line arg by VMwareUser.
- */
-
-void
-CopyPasteDnDWrapper::SetBlockControl(DnDBlockControl *blockCtrl)
-{
-   Debug("%s: enter %p (%d)\n", __func__, blockCtrl, blockCtrl->fd);
-   m_blockCtrl = blockCtrl;
-}
-
-
-/**
- *
- * Register copy and paste capabilities with the VMX. Try newest version
- * first, then fall back to the legacy implementation.
- *
- * @return TRUE on success, FALSE on failure
- */
-
-bool
-CopyPasteDnDWrapper::RegisterCP()
-{
-   Debug("%s: m_blockCtrl %p\n", __func__, m_blockCtrl);
-   if (IsCPRegistered()) {
-      return TRUE;
-   }
-
-   /*
-    * Try to get version 3, and if that fails, go for the compatibility
-    * versions (1 and 2).
-    */
-
-#if defined(HAVE_GTKMM)
-   if (!IsCPRegistered()) {
-      m_copyPasteUI = new CopyPasteUI();
-      if (m_copyPasteUI) {
-         Debug("%s: Setting block control to %p (fd %d)\n",
-               __func__, m_blockCtrl, m_blockCtrl->fd);
-         m_copyPasteUI->SetBlockControl(m_blockCtrl);
-         if (m_copyPasteUI->Init()) {
-            SetCPIsRegistered(TRUE);
-            int version = GetCPVersion();
-            Debug("%s: version is %d\n", __FUNCTION__, version);
-            if (version >= 3) {
-               m_copyPasteUI->VmxCopyPasteVersionChanged(gRpcIn, version);
-               m_copyPasteUI->SetCopyPasteAllowed(TRUE);
-               m_isLegacy = false;
-            } else {
-               Debug("%s: version < 3, unregistering.\n", __FUNCTION__);
-               UnregisterCP();
-            }
-         } else {
-            delete m_copyPasteUI;
-            m_copyPasteUI = NULL;
-         }
-      }
-   }
-
-#endif
-   if (!IsCPRegistered()) {
-      Debug("%s: Registering legacy m_userData %lx\n",
-            __func__, (long unsigned int) m_userData);
-      SetCPIsRegistered(CopyPaste_Register((GtkWidget *)m_userData));
-      if (IsCPRegistered()) {
-         Debug("%s: Registering capability\n", __FUNCTION__);
-         if (!CopyPaste_RegisterCapability()) {
-            UnregisterCP();
-         }
-         else {
-            m_isLegacy = true;
-         }
-      }
-   }
-
-   return IsCPRegistered();
-}
-
-
-/**
- *
- * Cancel DnD and copy paste.
- */
-
-void
-CopyPasteDnDWrapper::Cancel()
-{
-#if defined(HAVE_GTKMM)
-   if (m_dndUI) {
-      m_dndUI->Cancel();
-   }
-   if (m_copyPasteUI) {
-      m_copyPasteUI->Cancel();
-   }
-#endif
-}
-
-
-/**
- *
- * Register DnD capabilities with the VMX. Try newest version
- * first, then fall back to the legacy implementation.
- *
- * @return TRUE on success, FALSE on failure
- */
-
-bool
-CopyPasteDnDWrapper::RegisterDnD()
-{
-   /*
-    * Try to get version 3, and if that fails, go for the compatibility
-    * versions (1 and 2).
-    */
-
-#if defined(HAVE_GTKMM)
-   if (!IsDnDRegistered()) {
-      m_dndUI = new DnDUI(m_eventQueue);
-      if (m_dndUI) {
-         Debug("%s: Setting block control to %p (fd %d)\n",
-               __func__, m_blockCtrl, m_blockCtrl->fd);
-         m_dndUI->SetBlockControl(m_blockCtrl);
-
-         if (m_dndUI->Init()) {
-            UnityDnD state;
-            state.detWnd = m_dndUI->GetDetWndAsWidget();
-            state.setMode = CopyPasteDnDWrapper_SetUnityMode;
-            Unity_SetActiveDnDDetWnd(&state);
-
-            SetDnDIsRegistered(TRUE);
-            int version = GetDnDVersion();
-            Debug("%s: dnd version is %d\n", __FUNCTION__, version);
-            if (version >= 3) {
-               Debug("%s: calling VmxDnDVersionChanged (version %d) and SetDnDAllowed\n",
-                     __FUNCTION__, version);
-               m_dndUI->VmxDnDVersionChanged(gRpcIn, version);
-               m_dndUI->SetDnDAllowed(TRUE);
-               m_isLegacy = false;
-            } else {
-               Debug("%s: version < 3, unregistering.\n", __FUNCTION__);
-               UnregisterDnD();
-            }
-         } else {
-            delete m_dndUI;
-            m_dndUI = NULL;
-         }
-      }
-   }
-
-#endif
-   if (!IsDnDRegistered()) {
-      Debug("%s: legacy registering dnd capability\n", __FUNCTION__);
-      if (m_isLegacy) {
-         SetDnDIsRegistered(DnD_Register(m_hgWnd, m_ghWnd));
-         if (IsDnDRegistered()) {
-            Debug("%s: setting up detwnd for Unity\n", __FUNCTION__);
-            UnityDnD state;
-            state.detWnd = m_ghWnd;
-            state.setMode = DnD_SetMode;
-            Unity_SetActiveDnDDetWnd(&state);
-         }
-      }
-   } else if (m_isLegacy && DnD_GetVmxDnDVersion() > 1) {
-      Debug("%s: legacy registering dnd capability\n", __FUNCTION__);
-      if (!DnD_RegisterCapability()) {
-         Debug("%s: legacy unable to register dnd capability\n", __FUNCTION__);
-         UnregisterDnD();
-      }
-   }
-   Debug("%s: dnd is registered? %d\n", __FUNCTION__, (int) IsDnDRegistered());
-   return IsDnDRegistered();
-}
-
-
-/**
- *
- * Unregister copy paste capabilities and do general cleanup.
- */
-
-void
-CopyPasteDnDWrapper::UnregisterCP()
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   if (IsCPRegistered()) {
-#if defined(HAVE_GTKMM)
-      if (m_copyPasteUI) {
-         delete m_copyPasteUI;
-         m_copyPasteUI = NULL;
-      } else {
-#endif
-         CopyPaste_Unregister((GtkWidget *)m_userData);
-#if defined(HAVE_GTKMM)
-      }
-#endif
-      SetCPIsRegistered(FALSE);
-      m_cpVersion = -1;
-   }
-}
-
-
-/**
- *
- * Unregister DnD capabilities and do general cleanup.
- */
-
-void
-CopyPasteDnDWrapper::UnregisterDnD()
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   if (IsDnDRegistered()) {
-      /*
-       * Detach the DnD detection window from Unity.
-       */
-      UnityDnD state = { NULL, NULL };
-      Unity_SetActiveDnDDetWnd(&state);
-
-      if (m_isLegacy) {
-         DnD_Unregister(m_hgWnd, m_ghWnd);
-#if defined(HAVE_GTKMM)
-      } else if (m_dndUI) {
-         delete m_dndUI;
-         m_dndUI = NULL;
-#endif
-      }
-      m_dndVersion = -1;
-      SetDnDIsRegistered(false);
-      return;
-   }
-}
-
-
-/**
- *
- * Get the version of the copy paste protocol being wrapped.
- *
- * @return copy paste protocol version.
- */
-
-int
-CopyPasteDnDWrapper::GetCPVersion()
-{
-   if (IsCPRegistered()) {
-      m_cpVersion = CopyPaste_GetVmxCopyPasteVersion();
-   }
-   Debug("%s: got version %d\n", __FUNCTION__, m_cpVersion);
-   return m_cpVersion;
-}
-
-
-/**
- *
- * Get the version of the DnD protocol being wrapped.
- *
- * @return DnD protocol version.
- */
-
-int
-CopyPasteDnDWrapper::GetDnDVersion()
-{
-   if (IsDnDRegistered()) {
-      m_dndVersion = DnD_GetVmxDnDVersion();
-   }
-   Debug("%s: got version %d\n", __FUNCTION__, m_dndVersion);
-   return m_dndVersion;
-}
-
-
-/**
- *
- * Set a flag indicating that we are wrapping an initialized and registered
- * copy paste implementation, or not.
- *
- * @param[in] isRegistered If TRUE, protocol is registered, otherwise FALSE.
- */
-
-void
-CopyPasteDnDWrapper::SetCPIsRegistered(bool isRegistered)
-{
-   m_isCPRegistered = isRegistered;
-}
-
-
-/**
- *
- * Get the flag indicating that we are wrapping an initialized and registered
- * copy paste implementation, or not.
- *
- * @return TRUE if copy paste is initialized, otherwise FALSE.
- */
-
-bool
-CopyPasteDnDWrapper::IsCPRegistered()
-{
-   return m_isCPRegistered;
-}
-
-
-/**
- *
- * Set a flag indicating that we are wrapping an initialized and registered
- * DnD implementation, or not.
- *
- * @param[in] isRegistered If TRUE, protocol is registered, otherwise FALSE.
- */
-
-void
-CopyPasteDnDWrapper::SetDnDIsRegistered(bool isRegistered)
-{
-   m_isDnDRegistered = isRegistered;
-}
-
-
-/**
- *
- * Get the flag indicating that we are wrapping an initialized and registered
- * DnD implementation, or not.
- *
- * @return TRUE if DnD is initialized, otherwise FALSE.
- */
-
-bool
-CopyPasteDnDWrapper::IsDnDRegistered()
-{
-   return m_isDnDRegistered;
-}
-
-
-/**
- *
- * Handle reset by calling protocol dependent handlers.
- */
-
-void
-CopyPasteDnDWrapper::OnReset()
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   if (IsDnDRegistered()) {
-      UnregisterDnD();
-   }
-   if (IsCPRegistered()) {
-      UnregisterCP();
-   }
-   if (!IsCPRegistered()) {
-      RegisterCP();
-   }
-   if (!IsDnDRegistered()) {
-      RegisterDnD();
-   }
-   if (!IsDnDRegistered() || !IsCPRegistered()) {
-      Debug("%s: unable to reset fully!\n", __FUNCTION__);
-   }
-   if (m_isLegacy) {
-      if (IsCPRegistered()) {
-         CopyPaste_OnReset();
-      }
-      if (IsDnDRegistered()) {
-         DnD_OnReset(m_hgWnd, m_ghWnd);
-      }
-   }
-}
-
diff --git a/open-vm-tools/vmware-user/copyPasteDnDWrapper.h b/open-vm-tools/vmware-user/copyPasteDnDWrapper.h
deleted file mode 100644 (file)
index 474c672..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/**
- * @file copyPasteDnDWrapper.h
- *
- * This singleton class implements a wrapper around various versions of
- * copy and paste and dnd versions for Linux.
- *
- */
-
-#ifndef COPYPASTEDNDWRAPPER_H
-#define COPYPASTEDNDWRAPPER_H
-
-extern "C" {
-#include "dnd.h"     /* for DnDBlockControl */
-}
-
-#if defined(HAVE_GTKMM)
-#include "copyPasteUI.h"
-#include "dndUI.h"
-#endif
-
-#include "vm_basic_types.h"
-#include <gtk/gtk.h>
-
-struct DblLnkLst_Links;
-
-extern "C" {
-void CopyPasteDnDWrapper_SetUnityMode(Bool mode);
-}
-
-class CopyPasteDnDWrapper
-{
-public:
-   ~CopyPasteDnDWrapper();
-   static CopyPasteDnDWrapper *GetInstance();
-   bool RegisterCP();
-   void UnregisterCP();
-   bool RegisterDnD();
-   void UnregisterDnD();
-   int GetCPVersion();
-   int GetDnDVersion();
-   void SetCPIsRegistered(bool isRegistered);
-   bool IsCPRegistered();
-   void SetDnDIsRegistered(bool isRegistered);
-   bool IsDnDRegistered();
-   void OnReset();
-   void Cancel();
-   void SetBlockControl(DnDBlockControl *blockCtrl);
-   void SetUserData(const void *userData);
-   void SetHGWnd(GtkWidget *wnd) {m_hgWnd = wnd;};
-   void SetGHWnd(GtkWidget *wnd) {m_ghWnd = wnd;};
-   void SetEventQueue(DblLnkLst_Links *queue) {m_eventQueue = queue;};
-#if defined(HAVE_GTKMM)
-   void SetUnityMode(Bool mode)
-      {m_dndUI->SetUnityMode(mode);};
-#endif
-private:
-   /*
-    * We're a singleton, so it is a compile time error to call these.
-    */
-   CopyPasteDnDWrapper();
-   CopyPasteDnDWrapper(const CopyPasteDnDWrapper &wrapper);
-   CopyPasteDnDWrapper& operator=(const CopyPasteDnDWrapper &wrapper);
-private:
-#if defined(HAVE_GTKMM)
-   CopyPasteUI *m_copyPasteUI;
-   DnDUI *m_dndUI;
-#endif
-   bool m_isCPRegistered;
-   bool m_isDnDRegistered;
-   const void *m_userData;
-   int m_cpVersion;
-   int m_dndVersion;
-   static CopyPasteDnDWrapper *m_instance;
-   DnDBlockControl *m_blockCtrl;
-   bool m_isLegacy;
-   GtkWidget *m_hgWnd;
-   GtkWidget *m_ghWnd;
-   DblLnkLst_Links *m_eventQueue;
-};
-
-#endif // COPYPASTEDNDWRAPPER_H
diff --git a/open-vm-tools/vmware-user/copyPasteUI.cpp b/open-vm-tools/vmware-user/copyPasteUI.cpp
deleted file mode 100644 (file)
index 46f9236..0000000
+++ /dev/null
@@ -1,1426 +0,0 @@
-/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * copyPasteUI.cpp --
- *
- *    This class implements the methods that allows CopyPaste between host
- *    and guest.
- *
- *    For a perspective on X copy/paste, see
- *    http://www.jwz.org/doc/x-cut-and-paste.html
- */
-
-#include <sys/time.h>
-#include <time.h>
-#include "copyPasteUI.h"
-#include "dndFileList.hh"
-
-extern "C" {
-   #include "vmwareuserInt.h"
-   #include "vmblock.h"
-   #include "file.h"
-   #include "dnd.h"
-   #include "dndMsg.h"
-   #include "dndClipboard.h"
-   #include "cpName.h"
-   #include "debug.h"
-   #include "cpNameUtil.h"
-   #include "rpcout.h"
-   #include "eventManager.h"
-   #include "vmware/guestrpc/tclodefs.h"
-}
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::CopyPasteUI --
- *
- *    Constructor.
- *
- * Results:
- *    None
- *
- * Side effects:
- *    None
- *
- *-----------------------------------------------------------------------------
- */
-
-CopyPasteUI::CopyPasteUI()
- : mClipboardEmpty(true),
-   mHGStagingDir(""),
-   mIsClipboardOwner(false),
-   mHGGetFilesInitiated(false),
-   mFileTransferDone(false),
-   mBlockAdded(false),
-   mBlockCtrl(0),
-   mInited(false)
-{
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::Init --
- *
- *    Initialize copy paste UI class and register for V3 or greater copy
- *    paste.
- *
- * Results:
- *    None
- *
- * Side effects:
- *    None
- *
- *-----------------------------------------------------------------------------
- */
-
-bool
-CopyPasteUI::Init()
-{
-   if (mInited) {
-      return true;
-   }
-
-   CPClipboard_Init(&mClipboard);
-
-   Gtk::TargetEntry gnome(FCP_TARGET_NAME_GNOME_COPIED_FILES);
-   Gtk::TargetEntry kde(FCP_TARGET_NAME_URI_LIST);
-   gnome.set_info(FCP_TARGET_INFO_GNOME_COPIED_FILES);
-   kde.set_info(FCP_TARGET_INFO_URI_LIST);
-
-   mListTargets.push_back(gnome);
-   mListTargets.push_back(kde);
-
-   /* Tell the VMX about the copyPaste version we support. */
-   if (!RpcOut_sendOne(NULL, NULL, "tools.capability.copypaste_version 3")) {
-      Debug("%s: could not set guest copypaste version capability\n",
-            __FUNCTION__);
-      return false;
-   }
-   Debug("%s: set copypaste version 3\n", __FUNCTION__);
-
-   mCP.newClipboard.connect(
-      sigc::mem_fun(this, &CopyPasteUI::GetRemoteClipboardCB));
-   mCP.localGetClipboard.connect(
-      sigc::mem_fun(this, &CopyPasteUI::GetLocalClipboard));
-   mCP.localGetFilesDoneChanged.connect(
-      sigc::mem_fun(this, &CopyPasteUI::GetLocalFilesDone));
-   mInited = true;
-   return true;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::~CopyPaste --
- *
- *    Destructor.
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    None.
- *
- *-----------------------------------------------------------------------------
- */
-
-CopyPasteUI::~CopyPasteUI()
-{
-   CPClipboard_Destroy(&mClipboard);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::Cancel --
- *
- *    Cancel file transfer and remove block.
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteUI::Cancel()
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   if (mBlockAdded) {
-      DnD_DeleteStagingFiles(mHGStagingDir.c_str(), FALSE);
-      Debug("%s: removing block for %s\n", __FUNCTION__, mHGStagingDir.c_str());
-      mBlockCtrl->RemoveBlock(mBlockCtrl->fd, mHGStagingDir.c_str());
-      mBlockAdded = false;
-   }
-
-   mFileTransferDone = true;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::VmxCopyPasteVersionChanged --
- *
- *      Update version information in mCP.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteUI::VmxCopyPasteVersionChanged(struct RpcIn *rpcIn, // IN
-                                        uint32 version)      // IN
-{
-   Debug("%s: new version is %d\n", __FUNCTION__, version);
-   mCP.VmxCopyPasteVersionChanged(rpcIn, version);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::GetLocalClipboard --
- *
- *    Retrives the data from local clipboard and sends it to host. Send empty
- *    data back if there is no data or can not get data successfully. For 
- *    guest->host copy/paste.
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    None.
- *
- *-----------------------------------------------------------------------------
- */
-
-bool
-CopyPasteUI::GetLocalClipboard(CPClipboard *clip) // OUT
-{
-   Debug("%s: enter.\n", __FUNCTION__);
-
-   if (mIsClipboardOwner) {
-      Debug("%s: is clipboard owner, set changed to false and return.\n", __FUNCTION__);
-      CPClipboard_SetChanged(clip, FALSE);
-      return true;
-   }
-
-   if (!mCP.IsCopyPasteAllowed()) {
-      Debug("%s: copyPaste is not allowed\n", __FUNCTION__);
-      return true;
-   }
-
-   Glib::RefPtr<Gtk::Clipboard> refClipboard =
-      Gtk::Clipboard::get(GDK_SELECTION_CLIPBOARD);
-
-   mClipTime = 0;
-   mPrimTime = 0;
-   mGHSelection = GDK_SELECTION_CLIPBOARD;
-   Debug("%s: retrieving timestamps\n", __FUNCTION__);
-   refClipboard->request_contents(TARGET_NAME_TIMESTAMP,
-      sigc::mem_fun(this, &CopyPasteUI::LocalClipboardTimestampCB));
-   return false;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::GetCurrentTime --
- *
- *    Get current time in microseconds. 
- *
- * Results:
- *    Time in microseconds.
- *
- * Side effects:
- *    None.
- *
- *-----------------------------------------------------------------------------
- */
-
-VmTimeType
-CopyPasteUI::GetCurrentTime(void)
-{
-   struct timeval tv;
-   VmTimeType curTime;
-
-   if (gettimeofday(&tv, NULL) != 0) {
-      Debug("%s: gettimeofday failed!\n", __FUNCTION__);
-      return (VmTimeType) 0;
-   }
-   curTime = (tv.tv_sec * 1000000 + tv.tv_usec);
-   return curTime;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::LocalGetFileRequestCB --
- *
- *      Callback from a file paste request from another guest application.
- *      Begins copying the files from host to guest and return the file list.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteUI::LocalGetFileRequestCB(Gtk::SelectionData& sd,        // IN:
-                                   guint info)                    // IN:
-{
-   Debug("%s: enter.\n", __FUNCTION__);
-   mHGCopiedUriList = "";
-   VmTimeType curTime;
-   mBlockAdded = false;
-
-   sd.set(sd.get_target().c_str(), "");
-
-   curTime = GetCurrentTime();
-
-   /*
-    * Some applications may ask for clipboard contents right after clipboard
-    * owner changed. So HG FCP will return nothing for some time after switch
-    * from guest OS to host OS.
-    */
-   if ((curTime - mHGGetListTime) < FCP_COPY_DELAY) {
-      Debug("%s: time delta less than FCP_COPY_DELAY, returning.\n",
-            __FUNCTION__);
-      return;
-   }
-
-   if (!mIsClipboardOwner || !mCP.IsCopyPasteAllowed()) {
-      Debug("%s: not clipboard ownder, or copy paste not allowed, returning.\n",
-            __FUNCTION__);
-      return;
-   }
-
-   Debug("%s: Got paste request, target is %s\n", __FUNCTION__,
-         sd.get_target().c_str());
-
-   /* Copy the files. */
-   if (!mHGGetFilesInitiated) {
-      utf::string str;
-      utf::string hgStagingDir;
-      utf::string stagingDirName;
-      utf::string pre;
-      utf::string post;
-      size_t index = 0;
-      mFileTransferDone = false;
-
-      hgStagingDir = static_cast<utf::string>(mCP.GetFiles());
-      Debug("%s: Getting files. Staging dir: %s", __FUNCTION__,
-            hgStagingDir.c_str());
-
-      if (0 == hgStagingDir.bytes()) {
-         Debug("%s: Can not create staging directory\n", __FUNCTION__);
-         return;
-      }
-      mHGGetFilesInitiated = true;
-
-      if (DnD_BlockIsReady(mBlockCtrl) && mBlockCtrl->AddBlock(mBlockCtrl->fd, hgStagingDir.c_str())) {
-         Debug("%s: add block for %s.\n",
-               __FUNCTION__, hgStagingDir.c_str());
-         mBlockAdded = true;
-      } else {
-         Debug("%s: unable to add block for %s.\n",
-               __FUNCTION__, hgStagingDir.c_str());
-      }
-
-      mHGStagingDir = hgStagingDir;
-
-      /* Provide URIs for each path in the guest's file list. */
-      if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) {
-         mHGCopiedUriList = "copy\n";
-         pre = FCP_GNOME_LIST_PRE;
-         post = FCP_GNOME_LIST_POST;
-      } else if (FCP_TARGET_INFO_URI_LIST == info) {
-         pre = DND_URI_LIST_PRE_KDE;
-         post = DND_URI_LIST_POST;
-      } else {
-         Debug("%s: Unknown request target: %s\n", __FUNCTION__,
-               sd.get_target().c_str());
-         return;
-      }
-
-      /* Provide path within vmblock file system instead of actual path. */
-      stagingDirName = GetLastDirName(hgStagingDir);
-      if (0 == stagingDirName.bytes()) {
-         Debug("%s: Can not get staging directory name\n", __FUNCTION__);
-         return;
-      }
-
-      while ((str = GetNextPath(mHGFCPData, index).c_str()).bytes() != 0) {
-         Debug("%s: Path: %s", __FUNCTION__, str.c_str());
-         mHGCopiedUriList += pre;
-         if (mBlockAdded) {
-            mHGCopiedUriList += mBlockCtrl->blockRoot;
-            mHGCopiedUriList += DIRSEPS + stagingDirName + DIRSEPS + str + post;
-         } else {
-            mHGCopiedUriList += DIRSEPS + hgStagingDir + DIRSEPS + str + post;
-         }
-      }
-
-      /* Nautilus does not expect FCP_GNOME_LIST_POST after the last uri. See bug 143147. */
-      if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) {
-         mHGCopiedUriList.erase(mHGCopiedUriList.size() - 1, 1);
-      }
-   }
-
-   if (0 == mHGCopiedUriList.bytes()) {
-      Debug("%s: Can not get uri list\n", __FUNCTION__);
-      return;
-   }
-
-   if (!mBlockAdded) {
-      /*
-       * If there is no blocking driver, wait here till file copy is done.
-       * 2 reasons to keep this:
-       * 1. If run vmware-user stand-alone as non-root, blocking driver can
-       *    not be opened. Debug purpose only.
-       * 2. Other platforms (Solaris, etc) may also use this code,
-       *    and there is no blocking driver yet.
-       *
-       * Polling here will not be sufficient for large files (experiments
-       * showed it was sufficient for a 256MB file, and failed for a 1GB
-       * file, but those numbers are of course context-sensitive and so YMMV).
-       * The reason is we are executing in the context of gtkmm callback, and
-       * apparently it only has so much patience regarding how quickly we
-       * return.
-       */
-      Debug("%s no blocking driver, waiting for "
-            "HG file copy done ... mFileTransferDone is %d\n", __FUNCTION__,
-            (int) mFileTransferDone);
-      while (mFileTransferDone == false) {
-         struct timeval tv;
-         int nr;
-
-         tv.tv_sec = 0;
-         nr = EventManager_ProcessNext(gEventQueue, (uint64 *)&tv.tv_usec);
-         if (nr != 1) {
-            Debug("%s: unexpected end of loop: returned "
-                  "value is %d.\n", __FUNCTION__, nr);
-            return;
-         }
-         if (select(0, NULL, NULL, NULL, &tv) == -1) {
-            Debug("%s: error in select (%s).\n", __FUNCTION__,
-                  strerror(errno));
-            return;
-         }
-      }
-      Debug("%s: file transfer done!\n", __FUNCTION__);
-   }
-
-   Debug("%s: providing file list [%s]\n", __FUNCTION__,
-         mHGCopiedUriList.c_str());
-
-   sd.set(sd.get_target().c_str(), mHGCopiedUriList.c_str());
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::LocalGetTextOrRTFRequestCB --
- *
- *      Callback from a text or RTF paste request from another guest application.
- *      H->G copy paste only.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteUI::LocalGetTextOrRTFRequestCB(Gtk::SelectionData& sd, // IN/OUT
-                                        guint info)             // Ignored
-{
-   sd.set(sd.get_target().c_str(), "");
-
-   if (!mCP.IsCopyPasteAllowed()) {
-      return;
-   }
-
-   const utf::string target = sd.get_target().c_str();
-
-   Debug("%s: Got paste request, target is %s\n",
-         __FUNCTION__, target.c_str());
-
-   if (target == TARGET_NAME_APPLICATION_RTF ||
-       target == TARGET_NAME_TEXT_RICHTEXT) {
-      if (0 == mHGRTFData.bytes()) {
-         Debug("%s: Can not get valid RTF data\n", __FUNCTION__);
-         return;
-      }
-
-      Debug("%s: providing RTF data, size %"FMTSZ"u\n",
-            __FUNCTION__, mHGRTFData.bytes());
-
-      sd.set(target.c_str(), mHGRTFData.c_str());
-   }
-
-   if (target == TARGET_NAME_STRING ||
-       target == TARGET_NAME_TEXT_PLAIN ||
-       target == TARGET_NAME_UTF8_STRING ||
-       target == TARGET_NAME_COMPOUND_TEXT) {
-      if (0 == mHGTextData.bytes()) {
-         Debug("%s: Can not get valid text data\n", __FUNCTION__);
-         return;
-      }
-      Debug("%s: providing plain text, size %"FMTSZ"u\n",
-            __FUNCTION__, mHGTextData.bytes());
-
-      sd.set(target.c_str(), mHGTextData.c_str());
-   }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPaste::LocalClearClipboardCB --
- *
- *      Clear clipboard request from another host application.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteUI::LocalClearClipboardCB(void)
-{
-   Debug("%s: got clear callback\n", __FUNCTION__);
-   mIsClipboardOwner = FALSE;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * CopyPasteUI::LocalClipboardTimestampCB --
- *
- *      Got the local clipboard timestamp. Ask for the primary timestamp.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-CopyPasteUI::LocalClipboardTimestampCB(const Gtk::SelectionData& sd)  // IN
-{
-   int length = sd.get_length();
-   Debug("%s: enter sd.get_length() %d.\n", __FUNCTION__,
-         length);
-   if (length == 4) {
-      mClipTime = ((uint32*) sd.get_data())[0];
-      Debug("%s: mClipTime: %"FMT64"u.", __FUNCTION__, mClipTime);
-   } else if (length == 8) {
-      mClipTime = ((uint64*) sd.get_data())[0];
-      Debug("%s: mClipTime: %"FMT64"u.", __FUNCTION__, mClipTime);
-   } else {
-      Debug("%s: Unable to get mClipTime.", __FUNCTION__);
-   }
-
-   Glib::RefPtr<Gtk::Clipboard> refClipboard
-      = Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
-   refClipboard->request_contents(TARGET_NAME_TIMESTAMP,
-      sigc::mem_fun(this, &CopyPasteUI::LocalPrimTimestampCB));
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * CopyPasteUI::LocalPrimTimestampCB --
- *
- *      Got the local primary timestamp. Choose the most recently changed
- *      clipboard and get the selection from it.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-CopyPasteUI::LocalPrimTimestampCB(const Gtk::SelectionData& sd)  // IN
-{
-   int length = sd.get_length();
-   Debug("%s: enter sd.get_length() is %d.\n", __FUNCTION__, length);
-   if (length == 4) {
-      mPrimTime = ((uint32*) sd.get_data())[0];
-      Debug("%s: mPrimTime: %"FMT64"u.", __FUNCTION__, mPrimTime);
-   } else if (length == 8) {
-      mPrimTime = ((uint64*) sd.get_data())[0];
-      Debug("%s: mPrimTime: %"FMT64"u.", __FUNCTION__, mPrimTime);
-   } else {
-      Debug("%s: Unable to get mPrimTime.", __FUNCTION__);
-   }
-
-   /* After got both timestamp, choose latest one as active selection. */
-   mGHSelection = GDK_SELECTION_PRIMARY;
-   if (mClipTime > mPrimTime) {
-      mGHSelection = GDK_SELECTION_CLIPBOARD;
-   }
-
-   Glib::RefPtr<Gtk::Clipboard> refClipboard;
-   bool flipped = false;
-again:
-   bool validDataInClip = false;
-   refClipboard = Gtk::Clipboard::get(mGHSelection);
-
-   Debug("%s: trying %s selection.\n", __FUNCTION__,
-          mGHSelection == GDK_SELECTION_PRIMARY ? "Primary" : "Clip");
-
-   CPClipboard_Clear(&mClipboard);
-
-   /* First check for URIs. This must always be done first */
-   bool haveURIs = false;
-   std::string format;
-   if (refClipboard->wait_is_target_available(FCP_TARGET_NAME_GNOME_COPIED_FILES)) {
-      format = FCP_TARGET_NAME_GNOME_COPIED_FILES;
-      haveURIs = true;
-   } else if (refClipboard->wait_is_target_available(FCP_TARGET_NAME_URI_LIST)) {
-      format = FCP_TARGET_NAME_URI_LIST;
-      haveURIs = true;
-   }
-
-   if (haveURIs) {
-      refClipboard->request_contents(format,
-                                     sigc::mem_fun(this,
-                                                   &CopyPasteUI::LocalReceivedFileListCB));
-      return;
-   }
-
-   /* Try to get image data from clipboard. */
-   Glib::RefPtr<Gdk::Pixbuf> img = refClipboard->wait_for_image();
-   gsize bufSize;
-   if (img) {
-      gchar *buf = NULL;
-
-      img->save_to_buffer(buf, bufSize, Glib::ustring("png"));
-      if (bufSize > 0  &&
-          bufSize <= (int)CPCLIPITEM_MAX_SIZE_V3 &&
-          CPClipboard_SetItem(&mClipboard, CPFORMAT_IMG_PNG,
-                              buf, bufSize)) {
-         mCP.SetRemoteClipboard(&mClipboard);
-         Debug("%s: Got PNG: %"FMTSZ"u\n", __FUNCTION__, bufSize);
-      } else {
-         Debug("%s: Failed to get PNG\n", __FUNCTION__);
-      }
-      g_free(buf);
-      return;
-   }
-
-   /* Try to get RTF data from clipboard. */
-   bool haveRTF = false;
-   if (refClipboard->wait_is_target_available(TARGET_NAME_APPLICATION_RTF)) {
-      Debug("%s: RTF is available\n", __FUNCTION__);
-      format = TARGET_NAME_APPLICATION_RTF;
-      haveRTF = true;
-   }
-   if (refClipboard->wait_is_target_available(TARGET_NAME_TEXT_RICHTEXT)) {
-      Debug("%s: RICHTEXT is available\n", __FUNCTION__);
-      format = TARGET_NAME_TEXT_RICHTEXT;
-      haveRTF = true;
-   }
-
-   if (haveRTF) {
-      /*
-       * There is a function for waiting for rtf data, but that was leading
-       * to crashes. It's use required we instantiate a class that implements
-       * Gtk::TextBuffer and then query that class for a reference to it's
-       * TextBuffer instance. This all compiled fine but crashed in testing
-       * so we opt to use the more generic API here which seemed more stable.
-       */
-      Gtk::SelectionData sdata = refClipboard->wait_for_contents(format);
-      bufSize = sdata.get_length();
-      if (bufSize > 0  &&
-          bufSize <= (int)CPCLIPITEM_MAX_SIZE_V3 &&
-          CPClipboard_SetItem(&mClipboard, CPFORMAT_RTF,
-                              (const void *)sdata.get_data(), bufSize + 1)) {
-         validDataInClip = true;
-         Debug("%s: Got RTF\n", __FUNCTION__);
-      } else {
-         Debug("%s: Failed to get RTF size %d max %d\n",
-               __FUNCTION__, (int) bufSize, (int)CPCLIPITEM_MAX_SIZE_V3);
-      }
-   }
-
-   /* Try to get Text data from clipboard. */
-   if (refClipboard->wait_is_text_available()) {
-      Debug("%s: ask for text\n", __FUNCTION__);
-      Glib::ustring str = refClipboard->wait_for_text();
-      bufSize = str.bytes();
-      if (bufSize > 0  &&
-          bufSize <= (int)CPCLIPITEM_MAX_SIZE_V3 &&
-          CPClipboard_SetItem(&mClipboard, CPFORMAT_TEXT,
-                              (const void *)str.data(), bufSize + 1)) {
-         validDataInClip = true;
-         Debug("%s: Got TEXT: %"FMTSZ"u\n", __FUNCTION__, bufSize);
-      } else {
-         Debug("%s: Failed to get TEXT\n", __FUNCTION__);
-      }
-   }
-
-   if (validDataInClip) {
-      /*
-       * RTF or text data (or both) in the clipboard.
-       */
-      mCP.SetRemoteClipboard(&mClipboard);
-   } else if (!flipped) {
-      /*
-       * If we get here, we got nothing (no image, URI, text) so
-       * try the other selection.
-       */
-      Debug("%s: got nothing for this selection, try the other.\n",
-            __FUNCTION__);
-      mGHSelection = mGHSelection == GDK_SELECTION_PRIMARY ?
-                     GDK_SELECTION_CLIPBOARD : GDK_SELECTION_PRIMARY;
-      flipped = true;
-      goto again;
-   }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * CopyPasteUI::LocalReceivedFileListCB --
- *
- *      Got clipboard or primary selection file list. Parse it and add
- *      it to the crossplaform clipboard. Send clipboard to the host.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-CopyPasteUI::LocalReceivedFileListCB(const Gtk::SelectionData& sd)        // IN
-{
-   Debug("%s: enter", __FUNCTION__);
-   const utf::string target = sd.get_target().c_str();
-
-   if (target == FCP_TARGET_NAME_GNOME_COPIED_FILES ||
-       target == FCP_TARGET_NAME_URI_LIST) {
-      LocalGetSelectionFileList(sd);
-      mCP.SetRemoteClipboard(&mClipboard);
-   }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::LocalGetFileContentsRequestCB --
- *
- *      Callback from a file paste request from another guest application.
- *      Return the file list.
- *
- *      H->G only.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteUI::LocalGetFileContentsRequestCB(Gtk::SelectionData& sd, // IN
-                                           guint info)             // IN
-{
-   std::vector<utf::string>::const_iterator iter;
-   utf::string uriList = "";
-   utf::string pre;
-   utf::string post;
-
-   sd.set(sd.get_target().c_str(), "");
-
-   /* Provide URIs for each path in the guest's file list. */
-   if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) {
-      uriList = "copy\n";
-      pre = FCP_GNOME_LIST_PRE;
-      post = FCP_GNOME_LIST_POST;
-   } else if (FCP_TARGET_INFO_URI_LIST == info) {
-      pre = DND_URI_LIST_PRE_KDE;
-      post = DND_URI_LIST_POST;
-   } else {
-      Debug("%s: Unknown request target: %s\n",
-            __FUNCTION__, sd.get_target().c_str());
-      return;
-   }
-
-   for (iter = mHGFileContentsList.begin();
-        iter != mHGFileContentsList.end();
-        iter++) {
-      uriList += pre + *iter + post;
-   }
-
-   /* Nautilus does not expect FCP_GNOME_LIST_POST after the last uri. See bug 143147. */
-   if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) {
-      uriList.erase(uriList.size() - 1, 1);
-   }
-
-   if (0 == uriList.bytes()) {
-      Debug("%s: Can not get uri list\n", __FUNCTION__);
-      return;
-   }
-
-   Debug("%s: providing file list [%s]\n", __FUNCTION__, uriList.c_str());
-
-   sd.set(sd.get_target().c_str(), uriList.c_str());
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::LocalGetSelectionFileList --
- *
- *      Construct local file list and remote file list from selection data.
- *      Called by both DnD and FCP.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteUI::LocalGetSelectionFileList(const Gtk::SelectionData& sd)      // IN
-{
-   utf::string source;
-   char *newPath;
-   char *newRelPath;
-   size_t newPathLen;
-   size_t index = 0;
-   DnDFileList fileList;
-   DynBuf buf;
-   uint64 totalSize = 0;
-   int64 size;
-
-   /*
-    * Turn the uri list into two \0  delimited lists. One for full paths and
-    * one for just the last path component.
-    */
-   source = sd.get_data_as_string().c_str();
-   Debug("%s: Got file list: [%s]\n", __FUNCTION__, source.c_str());
-
-   /*
-    * In gnome, before file list there may be a extra line indicating it
-    * is a copy or cut.
-    */
-   if (source.startsWith("copy\n")) {
-      source = source.erase(0, 5);
-   }
-
-   if (source.startsWith("cut\n")) {
-      source = source.erase(0, 4);
-   }
-
-   while (source.bytes() > 0 &&
-          (source[0] == '\n' || source[0] == '\r' || source[0] == ' ')) {
-      source = source.erase(0, 1);
-   }
-
-   while ((newPath = DnD_UriListGetNextFile(source.c_str(),
-                                            &index,
-                                            &newPathLen)) != NULL) {
-
-      /*
-       * Parse relative path.
-       */
-      newRelPath = Str_Strrchr(newPath, DIRSEPC) + 1; // Point to char after '/'
-
-      /*
-       * XXX For directory, value is -1, so if there is any directory,
-       * total size is not accurate.
-       */
-      if ((size = File_GetSize(newPath)) >= 0) {
-         totalSize += size;
-      } else {
-         Debug("%s: Unable to get file size for %s\n", __FUNCTION__, newPath);
-      }
-
-      Debug("%s: Adding newPath '%s' newRelPath '%s'\n", __FUNCTION__,
-            newPath, newRelPath);
-      fileList.AddFile(newPath, newRelPath);
-      free(newPath);
-   }
-
-   DynBuf_Init(&buf);
-   fileList.SetFileSize(totalSize);
-   Debug("%s: totalSize is %"FMT64"u\n", __FUNCTION__, totalSize);
-   fileList.ToCPClipboard(&buf, false);
-   CPClipboard_SetItem(&mClipboard, CPFORMAT_FILELIST, DynBuf_Get(&buf),
-                       DynBuf_GetSize(&buf));
-   DynBuf_Destroy(&buf);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::GetLastDirName --
- *
- *      Try to get last directory name from a full path name.
- *
- * Results:
- *      Last dir name in the full path name if sucess, empty str otherwise
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-utf::string
-CopyPasteUI::GetLastDirName(const utf::string &str)     // IN
-{
-   utf::string ret;
-   size_t start;
-   size_t end;
-
-   end = str.bytes() - 1;
-   if (end >= 0 && DIRSEPC == str[end]) {
-      end--;
-   }
-
-   if (end <= 0 || str[0] != DIRSEPC) {
-      return "";
-   }
-
-   start = end;
-
-   while (str[start] != DIRSEPC) {
-      start--;
-   }
-
-   return str.substr(start + 1, end - start);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * CopyPasteUI::GetNextPath --
- *
- *      Provides a substring containing the next path from the provided
- *      NUL-delimited string starting at the provided index.
- *
- * Results:
- *      A string with the next path or "" if there are no more paths.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------------
- */
-
-utf::utf8string
-CopyPasteUI::GetNextPath(utf::utf8string& str,    // IN: NUL-delimited path list
-                         size_t& index)           // IN/OUT: current index into string
-{
-   utf::utf8string ret;
-   size_t start;
-
-   if (index >= str.length()) {
-      return "";
-   }
-
-   for (start = index; str[index] != '\0' && index < str.length(); index++) {
-      /*
-       * Escape reserved characters according to RFC 1630.  We'd use
-       * Escape_Do() if this wasn't a utf::string, but let's use the same table
-       * replacement approach.
-       */
-      static char const Dec2Hex[] = {
-         '0', '1', '2', '3', '4', '5', '6', '7',
-         '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
-      };
-
-      unsigned char ubyte = str[index];
-
-      if (ubyte == '#' ||   /* Fragment identifier delimiter */
-          ubyte == '?' ||   /* Query string delimiter */
-          ubyte == '*' ||   /* "Special significance within specific schemes" */
-          ubyte == '!' ||   /* "Special significance within specific schemes" */
-          ubyte == '%' ||   /* Escape character */
-          ubyte >= 0x80) {  /* UTF-8 encoding bytes */
-         str.replace(index, 1, "%");
-         str.insert(index + 1, 1, Dec2Hex[ubyte >> 4]);
-         str.insert(index + 2, 1, Dec2Hex[ubyte & 0xF]);
-         index += 2;
-      }
-   }
-
-   ret = str.substr(start, index - start);
-   Debug("%s: nextpath: %s", __FUNCTION__, ret.c_str());
-   index++;
-   return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::GetRemoteClipboardCB --
- *
- *    Invoked when got data from host. Update the internal data to get the file
- *    names or the text that needs to be transferred.
- *
- *    Method for copy and paste from host to guest.
- *
- * Results:
- *    None
- *
- * Side effects:
- *    None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteUI::GetRemoteClipboardCB(const CPClipboard *clip) // IN
-{
-   Glib::RefPtr<Gtk::Clipboard> refClipboard =
-      Gtk::Clipboard::get(GDK_SELECTION_CLIPBOARD);
-   Glib::RefPtr<Gtk::Clipboard> refPrimary =
-      Gtk::Clipboard::get(GDK_SELECTION_PRIMARY);
-   void *buf;
-   size_t sz;
-
-   Debug("%s: enter\n", __FUNCTION__);
-   if (!clip) {
-      Debug("%s: No clipboard contents.", __FUNCTION__);
-      return;
-   }
-
-   /* Clear the clipboard contents if we are the owner. */
-   if (mIsClipboardOwner) {
-      refClipboard->clear();
-      refPrimary->clear();
-      mIsClipboardOwner = FALSE;
-      Debug("%s: Cleared local clipboard", __FUNCTION__);
-   }
-
-   mHGTextData.clear();
-   mHGRTFData.clear();
-   mHGFCPData.clear();
-
-   if (CPClipboard_ItemExists(clip, CPFORMAT_TEXT) ||
-       CPClipboard_ItemExists(clip, CPFORMAT_RTF)) {
-      std::list<Gtk::TargetEntry> targets;
-
-      if (CPClipboard_GetItem(clip, CPFORMAT_TEXT, &buf, &sz)) {
-         Gtk::TargetEntry stringText(TARGET_NAME_STRING);
-         Gtk::TargetEntry plainText(TARGET_NAME_TEXT_PLAIN);
-         Gtk::TargetEntry utf8Text(TARGET_NAME_UTF8_STRING);
-         Gtk::TargetEntry compountText(TARGET_NAME_COMPOUND_TEXT);
-
-         Debug("%s: Text data, size %"FMTSZ"u.\n", __FUNCTION__, sz);
-         targets.push_back(stringText);
-         targets.push_back(plainText);
-         targets.push_back(utf8Text);
-         targets.push_back(compountText);
-         mHGTextData = utf::string((const char *)buf, STRING_ENCODING_UTF8);
-
-         mIsClipboardOwner = TRUE;
-      }
-
-      if (CPClipboard_GetItem(clip, CPFORMAT_RTF, &buf, &sz)) {
-         Debug("%s: RTF data, size %"FMTSZ"u.\n", __FUNCTION__, sz);
-         Gtk::TargetEntry appRtf(TARGET_NAME_APPLICATION_RTF);
-         Gtk::TargetEntry textRtf(TARGET_NAME_TEXT_RICHTEXT);
-
-         targets.push_back(appRtf);
-         targets.push_back(textRtf);
-         mHGRTFData = utf::string((const char *)buf, STRING_ENCODING_UTF8);
-
-         mIsClipboardOwner = TRUE;
-      }
-
-      refClipboard->set(targets,
-                        sigc::mem_fun(this, &CopyPasteUI::LocalGetTextOrRTFRequestCB),
-                        sigc::mem_fun(this, &CopyPasteUI::LocalClearClipboardCB));
-      refPrimary->set(targets,
-                      sigc::mem_fun(this, &CopyPasteUI::LocalGetTextOrRTFRequestCB),
-                      sigc::mem_fun(this, &CopyPasteUI::LocalClearClipboardCB));
-      return;
-   }
-
-   if (CPClipboard_GetItem(clip, CPFORMAT_IMG_PNG, &buf, &sz)) {
-      Debug("%s: PNG data, size %"FMTSZ"u.\n", __FUNCTION__, sz);
-      /* Try to load buf into pixbuf, and write to local clipboard. */
-      Glib::RefPtr<Gdk::PixbufLoader> loader = Gdk::PixbufLoader::create();
-
-      if (loader) {
-         loader->write((const guint8 *)buf, sz);
-         loader->close();
-
-         refClipboard->set_image(loader->get_pixbuf());
-         refPrimary->set_image(loader->get_pixbuf());
-      }
-      return;
-   }
-   if (CPClipboard_GetItem(clip, CPFORMAT_FILELIST, &buf, &sz)) {
-      Debug("%s: File data.\n", __FUNCTION__);
-      DnDFileList flist;
-      flist.FromCPClipboard(buf, sz);
-      mHGFCPData = flist.GetRelPathsStr();
-
-      refClipboard->set(mListTargets,
-                        sigc::mem_fun(this, &CopyPasteUI::LocalGetFileRequestCB),
-                        sigc::mem_fun(this, &CopyPasteUI::LocalClearClipboardCB));
-      refPrimary->set(mListTargets,
-                      sigc::mem_fun(this, &CopyPasteUI::LocalGetFileRequestCB),
-                      sigc::mem_fun(this, &CopyPasteUI::LocalClearClipboardCB));
-
-      mIsClipboardOwner = TRUE;
-      mHGGetListTime = GetCurrentTime();
-      mHGGetFilesInitiated = false;
-      mHGCopiedUriList = "";
-   }
-
-   if (CPClipboard_ItemExists(clip, CPFORMAT_FILECONTENTS)) {
-      Debug("%s: File contents data\n", __FUNCTION__);
-      if (LocalPrepareFileContents(clip)) {
-         refClipboard->set(mListTargets,
-                           sigc::mem_fun(this, &CopyPasteUI::LocalGetFileContentsRequestCB),
-                           sigc::mem_fun(this, &CopyPasteUI::LocalClearClipboardCB));
-         refPrimary->set(mListTargets,
-                         sigc::mem_fun(this, &CopyPasteUI::LocalGetFileContentsRequestCB),
-                         sigc::mem_fun(this, &CopyPasteUI::LocalClearClipboardCB));
-         mIsClipboardOwner = TRUE;
-      }
-   }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * CopyPasteUI::LocalPrepareFileContents --
- *
- *      Try to extract file contents from mClipboard. Write all files to a
- *      temporary staging directory. Construct uri list.
- *
- * Results:
- *      true if success, false otherwise.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------------
- */
-
-bool
-CopyPasteUI::LocalPrepareFileContents(const CPClipboard *clip) // IN
-{
-   void *buf = NULL;
-   size_t sz = 0;
-   XDR xdrs;
-   CPFileContents fileContents;
-   CPFileContentsList *contentsList = NULL;
-   size_t nFiles = 0;
-   CPFileItem *fileItem = NULL;
-   Unicode tempDir = NULL;
-   size_t i = 0;
-   bool ret = false;
-
-   if (!CPClipboard_GetItem(clip, CPFORMAT_FILECONTENTS, &buf, &sz)) {
-      Debug("%s: CPClipboard_GetItem failed\n", __FUNCTION__);
-      return false;
-   }
-
-   /* Extract file contents from buf. */
-   xdrmem_create(&xdrs, (char *)buf, sz, XDR_DECODE);
-   memset(&fileContents, 0, sizeof fileContents);
-
-   if (!xdr_CPFileContents(&xdrs, &fileContents)) {
-      Debug("%s: xdr_CPFileContents failed.\n", __FUNCTION__);
-      xdr_destroy(&xdrs);
-      return false;
-   }
-   xdr_destroy(&xdrs);
-
-   contentsList = fileContents.CPFileContents_u.fileContentsV1;
-   if (!contentsList) {
-      Debug("%s: invalid contentsList.\n", __FUNCTION__);
-      goto exit;
-   }
-
-   nFiles = contentsList->fileItem.fileItem_len;
-   if (0 == nFiles) {
-      Debug("%s: invalid nFiles.\n", __FUNCTION__);
-      goto exit;
-   }
-
-   fileItem = contentsList->fileItem.fileItem_val;
-   if (!fileItem) {
-      Debug("%s: invalid fileItem.\n", __FUNCTION__);
-      goto exit;
-   }
-
-   /*
-    * Write files into a temporary staging directory. These files will be moved
-    * to final destination, or deleted on next reboot.
-    */
-   tempDir = DnD_CreateStagingDirectory();
-   if (!tempDir) {
-      Debug("%s: DnD_CreateStagingDirectory failed.\n", __FUNCTION__);
-      goto exit;
-   }
-
-   mHGFileContentsList.clear();
-
-   for (i = 0; i < nFiles; i++) {
-      utf::string fileName;
-      utf::string filePathName;
-      VmTimeType createTime = -1;
-      VmTimeType accessTime = -1;
-      VmTimeType writeTime = -1;
-      VmTimeType attrChangeTime = -1;
-
-      if (!fileItem[i].cpName.cpName_val ||
-          0 == fileItem[i].cpName.cpName_len) {
-         Debug("%s: invalid fileItem[%"FMTSZ"u].cpName.\n", __FUNCTION__, i);
-         goto exit;
-      }
-
-      /*
-       * '\0' is used as directory separator in cross-platform name. Now turn
-       * '\0' in data into DIRSEPC.
-       *
-       * Note that we don't convert the final '\0' into DIRSEPC so the string
-       * is NUL terminated.
-       */
-      CPNameUtil_CharReplace(fileItem[i].cpName.cpName_val,
-                             fileItem[i].cpName.cpName_len - 1,
-                             '\0',
-                             DIRSEPC);
-      fileName = fileItem[i].cpName.cpName_val;
-      filePathName = tempDir;
-      filePathName += DIRSEPS + fileName;
-
-      if (fileItem[i].validFlags & CP_FILE_VALID_TYPE &&
-          CP_FILE_TYPE_DIRECTORY == fileItem[i].type) {
-         if (!File_CreateDirectory(filePathName.c_str())) {
-            goto exit;
-         }
-         Debug("%s: created directory [%s].\n",
-                   __FUNCTION__, filePathName.c_str());
-      } else if (fileItem[i].validFlags & CP_FILE_VALID_TYPE &&
-                 CP_FILE_TYPE_REGULAR == fileItem[i].type) {
-         FileIODescriptor file;
-         FileIOResult fileErr;
-
-         FileIO_Invalidate(&file);
-
-         fileErr = FileIO_Open(&file,
-                               filePathName.c_str(),
-                               FILEIO_ACCESS_WRITE,
-                               FILEIO_OPEN_CREATE_EMPTY);
-         if (!FileIO_IsSuccess(fileErr)) {
-            goto exit;
-         }
-
-         fileErr = FileIO_Write(&file,
-                                fileItem[i].content.content_val,
-                                fileItem[i].content.content_len,
-                                NULL);
-
-         FileIO_Close(&file);
-         Debug("%s: created file [%s].\n", __FUNCTION__, filePathName.c_str());
-      } else {
-         /*
-          * Right now only Windows can provide CPFORMAT_FILECONTENTS data.
-          * Symlink file is not expected. Continue with next file if the
-          * type is not valid.
-          */
-         continue;
-      }
-
-      /* Update file time attributes. */
-      createTime = fileItem->validFlags & CP_FILE_VALID_CREATE_TIME ?
-         fileItem->createTime: -1;
-      accessTime = fileItem->validFlags & CP_FILE_VALID_ACCESS_TIME ?
-         fileItem->accessTime: -1;
-      writeTime = fileItem->validFlags & CP_FILE_VALID_WRITE_TIME ?
-         fileItem->writeTime: -1;
-      attrChangeTime = fileItem->validFlags & CP_FILE_VALID_CHANGE_TIME ?
-         fileItem->attrChangeTime: -1;
-
-      if (!File_SetTimes(filePathName.c_str(),
-                         createTime,
-                         accessTime,
-                         writeTime,
-                         attrChangeTime)) {
-         /* Not a critical error, only log it. */
-         Debug("%s: File_SetTimes failed with file [%s].\n",
-               __FUNCTION__, filePathName.c_str());
-      }
-
-      /* Update file permission attributes. */
-      if (fileItem->validFlags & CP_FILE_VALID_PERMS) {
-         if (Posix_Chmod(filePathName.c_str(),
-                         fileItem->permissions) < 0) {
-            /* Not a critical error, only log it. */
-            Debug("%s: Posix_Chmod failed with file [%s].\n",
-                  __FUNCTION__, filePathName.c_str());
-         }
-      }
-
-      /*
-       * If there is no DIRSEPC inside the fileName, this file/directory is a
-       * top level one. We only put top level name into uri list.
-       */
-      if (fileName.find(DIRSEPS, 0) == utf::string::npos) {
-         mHGFileContentsList.push_back(filePathName);
-      }
-   }
-   Debug("%s: created uri list\n", __FUNCTION__);
-   ret = true;
-
-exit:
-   xdr_free((xdrproc_t)xdr_CPFileContents, (char *)&fileContents);
-   if (tempDir && !ret) {
-      DnD_DeleteStagingFiles(tempDir, FALSE);
-   }
-   free(tempDir);
-   return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::GetLocalFilesDone --
- *
- *    Callback when CopyPasteUI::GetLocalFiles is done, which finishes the file
- *    copying from host to guest staging directory. This function notifies
- *    the Copy/Paste data object and end its waiting state in order to continue
- *    the file copying from local staging directory to local target directory.
- *
- * Results:
- *    None
- *
- * Side effects:
- *    None
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteUI::GetLocalFilesDone(bool success)
-{
-   Debug("%s: enter success %d\n", __FUNCTION__, success);
-
-   if (mBlockAdded) {
-      Debug("%s: removing block for %s\n", __FUNCTION__, mHGStagingDir.c_str());
-      mBlockCtrl->RemoveBlock(mBlockCtrl->fd, mHGStagingDir.c_str());
-      mBlockAdded = false;
-   }
-
-   mFileTransferDone = true;
-   if (success) {
-      /*
-       * Mark current staging dir to be deleted on next reboot for FCP. The
-       * file will not be deleted after reboot if it is moved to another
-       * location by target application.
-       */
-      DnD_DeleteStagingFiles(mHGStagingDir.c_str(), TRUE);
-   } else {
-      /* Copied files are already removed in common layer. */
-      mHGStagingDir.clear();
-   }
-   mHGGetFilesInitiated = false;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * CopyPasteUI::Reset --
- *
- *
- * Results:
- *    None
- *
- * Side effects:
- *    None
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-CopyPasteUI::Reset(void)
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   /* Cancel any pending file transfer. */
-}
-
diff --git a/open-vm-tools/vmware-user/copyPasteUI.h b/open-vm-tools/vmware-user/copyPasteUI.h
deleted file mode 100644 (file)
index 5bb4a79..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/**
- * @file copyPasteUI.h
- *
- * This class implements the methods that allows Copy/Paste
- * between host and guest using version 3+ of the protocol.
- *
- */
-
-#ifndef COPYPASTE_UI_H
-#define COPYPASTE_UI_H
-
-#include "stringxx/string.hh"
-
-extern "C" {
-#include "dnd.h"
-#include "debug.h"
-#include "str.h"
-#include "dndClipboard.h"
-#include "dynbuf.h"
-#include "../dnd/dndFileContentsUtil.h"
-#include "dynxdr.h"
-#include "cpNameUtil.h"
-#include "posix.h"
-}
-
-#include "unicodeOperations.h"
-
-#include "copyPaste.hh"
-
-#include <gtkmm.h>
-#include <list>
-#include <vector>
-
-class CopyPasteUI : public sigc::trackable
-{
-public:
-   CopyPasteUI();
-   virtual ~CopyPasteUI();
-   bool Init();
-   void VmxCopyPasteVersionChanged(struct RpcIn *rpcIn,
-                                   uint32 version);
-   void SetCopyPasteAllowed(bool isCopyPasteAllowed)
-      { mCP.SetCopyPasteAllowed(isCopyPasteAllowed); }
-   void Reset(void);
-   void Cancel(void);
-   void SetBlockControl(DnDBlockControl *blockCtrl)
-      { Debug("Setting mBlockCtrl to %p\n", blockCtrl);
-        mBlockCtrl = blockCtrl; }
-
-private:
-
-   /* hg */
-   void GetRemoteClipboardCB(const CPClipboard *clip);
-   void RemoteGetFilesDone(void);
-   void LocalGetFileRequestCB(Gtk::SelectionData& selection_data, guint info);
-   void LocalGetTextOrRTFRequestCB(Gtk::SelectionData& sd, guint info);
-   void LocalGetSelectionFileList(const Gtk::SelectionData& sd);
-   void LocalGetFileContentsRequestCB(Gtk::SelectionData& sd, guint info);
-   void LocalClearClipboardCB(void);
-
-   /* gh */
-   bool GetLocalClipboard(CPClipboard *clip);
-   void LocalClipboardTimestampCB(const Gtk::SelectionData& sd);
-   void LocalPrimTimestampCB(const Gtk::SelectionData& sd);
-   void LocalReceivedFileListCB(const Gtk::SelectionData& selection_data);
-   void GetLocalFilesDone(bool success);
-
-   /* Conversion methods. */
-   utf::utf8string GetNextPath(utf::utf8string &str, size_t& index);
-   utf::string GetLastDirName(const utf::string &str);
-   bool LocalPrepareFileContents(const CPClipboard *clip);
-
-   VmTimeType GetCurrentTime(void);
-
-   // Member variables
-   CopyPaste mCP;
-   bool mClipboardEmpty;
-   utf::string mHGStagingDir;
-   std::list<Gtk::TargetEntry> mListTargets;
-   bool mIsClipboardOwner;
-   uint64 mClipTime;
-   uint64 mPrimTime;
-   GdkAtom mGHSelection;
-   CPClipboard mClipboard;
-
-   /* File vars. */
-   bool mHGGetFilesInitiated;
-   VmTimeType mHGGetListTime;
-   utf::string mHGCopiedUriList;
-   utf::utf8string mHGFCPData;
-   utf::string mHGTextData;
-   utf::string mHGRTFData;
-   std::vector<utf::string> mHGFileContentsList;
-   bool mFileTransferDone;
-   bool mBlockAdded;
-   DnDBlockControl *mBlockCtrl;
-   bool mInited;
-};
-
-#endif // COPYPASTE_UI_H
diff --git a/open-vm-tools/vmware-user/debugStdio.c b/open-vm-tools/vmware-user/debugStdio.c
deleted file mode 100644 (file)
index c8ead38..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/*********************************************************
- * Copyright (C) 1998 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-
-/*
- * debug.c --
- *
- *    Platform specific debug routines
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#if defined(_WIN32) && defined(_MSC_VER)
-#   include <windows.h>
-#endif
-#if defined(N_PLAT_NLM)
-#   include "vmwtool.h"
-#endif
-
-
-#include "vmware.h"
-#include "debug.h"
-#include "util.h"
-#include "str.h"
-#include "fileIO.h"
-#include "file.h"
-#include "system.h"
-#include "unicode.h"
-
-static char debugFile[FILE_MAXPATH] = {0};
-static Bool debugEnabled = FALSE;
-static const char *debugPrefix = NULL;
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Debug_Set --
- *
- *    Enable/Disable debugging output
- *
- * Result
- *    None.
- *
- * Side-effects
- *    None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Debug_Set(Bool enable,        // IN
-          const char *prefix) // IN
-{
-   debugEnabled = enable;
-   debugPrefix = prefix;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Debug_EnableToFile --
- *
- *    Enable debugging output to the given file. If backup is TRUE, will rename
- *    existing file to file.old and start logging to a new file. Only daemon
- *    should set backup flag then will do backup for each reboot.
- *
- * Result
- *    None.
- *
- * Side-effects
- *    None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Debug_EnableToFile(const char *file,      // IN
-                   Bool backup)           // IN
-{
-   if (backup && file && File_Exists(file)) {
-      /* Back up existing log file. */
-      char *bakFile = Str_Asprintf(NULL, "%s.old", file);
-      if (bakFile &&
-          !File_IsDirectory(bakFile) &&
-          0 == File_UnlinkIfExists(bakFile)) {  // remove old back up file.
-         File_Rename(file, bakFile);
-      }
-      free(bakFile);
-   }
-   if (file) {
-      Str_Sprintf(debugFile, sizeof debugFile, "%s", file);
-      debugEnabled = TRUE;
-   } else {
-      debugFile[0] = '\0';
-   }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DebugToFile --
- *
- *    Print a string to the given file. This opens & closes the file
- *    handle each time it is called so it will significantly
- *    slow down the calling program. This is done so that the file
- *    can be opened & read while the program is running.
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    DebugToFile is turned off if there was an error opening the file.
- *
- *-----------------------------------------------------------------------------
- */
-
-static
-void DebugToFile(const char *str) // IN
-{
-#ifndef _CONSOLE
-   FileIOResult fr;
-   FileIODescriptor fd;
-   size_t bytesWritten;
-   Unicode timePrefix;
-   const char *timePrefixUtf8;
-   char debugFileShadow;
-
-   ASSERT(debugFile[0] != 0);
-
-   FileIO_Invalidate(&fd);
-
-   fr = FileIO_Open(&fd, debugFile, FILEIO_OPEN_ACCESS_WRITE,
-                    FILEIO_OPEN_CREATE);
-   debugFileShadow = debugFile[0];
-   debugFile[0] = '\0';
-   if (fr != FILEIO_SUCCESS) {
-      Warning("---Error opening file '%s'.\n", debugFile);
-      goto done;
-   }
-
-   /*
-    * XXX: Writing the date/time prefix in UTF-8 and the rest of the string in
-    * an unspecified encoding is rather broken, but it'll have to do until the
-    * rest of the Tools are made internationalization-safe.
-    */
-   timePrefix = System_GetTimeAsString();
-   if (timePrefix == NULL) {
-      Warning("---Error getting formatted time string.\n");
-      goto close;
-   }
-   timePrefixUtf8 = UTF8(timePrefix);
-   ASSERT(timePrefixUtf8);
-
-   FileIO_Seek(&fd, 0, FILEIO_SEEK_END);
-   fr = FileIO_Write(&fd, timePrefixUtf8, strlen(timePrefixUtf8), &bytesWritten);
-   fr = FileIO_Write(&fd, ": ", 2, &bytesWritten);
-   fr = FileIO_Write(&fd, str, strlen(str), &bytesWritten);
-   Unicode_Free(timePrefix);
-   if (fr != FILEIO_SUCCESS) {
-      Warning("---Error writing to file '%s'.\n", debugFile);
-   }
-
- close:
-   FileIO_Close(&fd);
-
- done:
-   debugFile[0] = debugFileShadow;
-   return;
-#endif // _CONSOLE
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Debug --
- *
- *    If debugging is enabled, output debug information
- *
- * Result
- *    None.
- *
- * Side-effects
- *    None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Debug(char const *fmt, // IN: Format string
-      ...)             // IN: Arguments
-{
-   va_list args;
-   char *str;
-   char *msg;
-
-   if (debugEnabled == FALSE) {
-      return;
-   }
-
-   va_start(args, fmt);
-   msg = Str_Vasprintf(NULL, fmt, args);
-   va_end(args);
-
-   str = Str_Asprintf(NULL, "[%s]: %s", debugPrefix ? debugPrefix : "NULL", msg);
-   free(msg);
-
-#ifdef N_PLAT_NLM
-   OutputToScreenWithAttribute(VMwareScreen, BOLD_RED, "%s", str);
-#else
-#ifdef _WIN32   
-   OutputDebugString(str);
-#endif
-#if !defined(_WIN32) || defined(_CONSOLE)
-   fputs(str, stderr);
-#endif
-#endif
-   if (debugFile[0] != '\0') {
-      DebugToFile(str);
-   }
-
-   free(str);
-}
diff --git a/open-vm-tools/vmware-user/dnd.c b/open-vm-tools/vmware-user/dnd.c
deleted file mode 100644 (file)
index 5a4fa05..0000000
+++ /dev/null
@@ -1,2710 +0,0 @@
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * dnd.c --
- *
- *  Handles the guest side of host<->guest DnD operations.
- *
- *  Guest->Host DnD
- *  ---------------
- *
- *  The DnD process within the guest starts when we receive a "dnd.ungrab" RPC
- *  message from the host, which invokes DnDRpcInMouseUngrabCB().  The MKS
- *  sends this RPC when it sees the mouse stray outside of the clip (guest's
- *  viewable area).  RpcInMouseUngrabCB() will determine whether a DnD is
- *  pending by calling DnDDragPending():
- *   o if a DnD is not pending, it replies with a "dnd.notpending" RPC and we
- *     are done,
- *   o if a DnD is pending, we send fake X events to the X server that place
- *     our invisible window at the location of the mouse pointer and generate
- *     mouse movements over the window.
- *
- *  Faking mouse movement over our window causes Gtk to send us a "drag_motion"
- *  signal, which invokes DnDGtkDragMotionCB().  Here we find a common target
- *  (drop type) and request the data from the drag source via
- *  gtk_drag_get_data().
- *
- *  When the data is ready, Gtk signals us with a "data_received" signal.  We
- *  parse the provided data and send the file names to the host with
- *  a "dnd.data.set" RPC.  Then we start the DnD operation with a "dnd.enter"
- *  RPC.  Upon receiving the "dnd.enter", the MKS will allow the ungrab of the
- *  mouse from the guest window and the user will be able to select a location
- *  to drop the files.
- *
- *  (Note that it is important that the guest reply to the "dnd.ungrab" with
- *   either a "dnd.notpending" or a "dnd.enter" in a timely manner, since the
- *   MKS will delay mouse packets until it has received a reply from the
- *   guest.)
- *
- *  When the user drops the files, the host will send us a "dnd.data.get.file"
- *  for each file, which invokes DnDRpcInGetNextFileCB().  On each invocation,
- *  we reply with the next file from the Guest->Host file list (obtained from
- *  DnDGHFileListGetNext()), and "|end|" when there are no more files.  With
- *  this information, the host copies the files from the guest using HGFS.
- *
- *  When the host has finished copying the files, it sends us a "dnd.finish"
- *  RPC, which invokes DnDRpcInFinishCB().  At this point, we fake X events
- *  that cause a mouse button release over our window.
- *
- *  This button release causes Gtk to send us a "drag_drop" signal, which
- *  invokes DnDGtkDragDropCB().  Here we simply clean up our state and
- *  indicate that the drag finished successfully by calling gtk_drag_finish().
- *
- *  If an error occurs at any point, the host sends us a "dnd.finish cancel"
- *  RPC.  We will fake an ESC key press and release to cancel the pending DnD
- *  in the guest.
- *
- *
- *  Host->Guest DnD
- *  ---------------
- *
- *  A host->guest DnD begins with a "dnd.data.set" from the vmx to provide the
- *  list of files being dragged into the guest, then a "dnd.enter" to begin the
- *  DnD operation.  When the "dnd.enter" is received, this process will send
- *  a fake mouse button press and mouse movement on its window, starting the
- *  DnD operation within the guest.  At this point the mouse still has not been
- *  grabbed by the guest and all mouse movements go only to the host.
- *
- *  As part of the normal DnD protocol on the host, the UI in the host will
- *  receive updates on the location of the mouse within its target window.
- *  This location is translated to guest coordinates and sent to us via the
- *  "dnd.move" RPC, at which point we fake additional mouse movements to that
- *  location.  When the user releases the mouse, the host UI is again notified
- *  and sends us a "dnd.drop" RPC.
- *
- *  When the drop occurs, we add a block (via vmblock) on the directory
- *  containing the files to be given to the target application, then fake
- *  a mouse release at the location of the drop.  This will cause the target
- *  application to request the data, which we provide through our
- *  "drag_data_get" handler (DnDGtkDataRequestCB()).  When the application
- *  attempts to access these files it will be blocked by vmblock.
- *
- *  After the drop is sent, the host will send the files to the hgfs server
- *  running inside this process, and will notify us when that transfer is
- *  complete via the "dnd.data.finish" RPC.  If the transfer is successful, we
- *  remove the block to allow the target application to access the files.  If
- *  the transfer is unsuccessful, we remove any partially copied files then
- *  remove the block; this has the effect of failing the DnD operation since
- *  the target cannot access the necessary files.  Once this is done, we
- *  generate a new file root within the staging directory and send that to the
- *  host for the next DnD operation.
- *
- *  Note that we used to fake the mouse release only after the data transfer
- *  completed (and Windows guests still behave that way), but this was changed
- *  since the Linux UI was modified to allow guest interaction while the
- *  progress dialog (for the file transfer) was displayed and updating.  This
- *  caused a lot of instability since the mouse was no longer in a predictable
- *  state when the fake release was sent.  vmblock let us work around this by
- *  changing where the block occurred.
- */
-
-
-#include <string.h>
-#include <stdlib.h>
-#include <X11/extensions/XTest.h>       /* for XTest*() */
-#include <X11/keysym.h>                 /* for XK_Escape */
-#include <X11/Xatom.h>                  /* for XA_WINDOW */
-
-#include "vmwareuserInt.h"
-#include "vm_assert.h"
-#include "vm_basic_defs.h"
-#include "eventManager.h"
-#include "debug.h"
-#include "strutil.h"
-#include "str.h"
-#include "file.h"
-#include "guestApp.h"
-#include "cpName.h"
-#include "cpNameUtil.h"
-#include "dnd.h"
-#include "util.h"
-#include "hgfsVirtualDir.h"
-#include "hgfsServerPolicy.h"
-#include "vmblock.h"
-#include "escape.h"
-#include "vmware/guestrpc/tclodefs.h"
-
-#define DND_MAX_PATH                    6144
-#define DRAG_TARGET_NAME_URI_LIST       "text/uri-list"
-#define DRAG_TARGET_INFO_URI_LIST       0
-#define DRAG_TARGET_NAME_TEXT_PLAIN     "text/plain"
-#define DRAG_TARGET_INFO_TEXT_PLAIN     1
-#define DRAG_TARGET_NAME_STRING         "STRING"
-#define DRAG_TARGET_INFO_STRING         2
-/*
- * We support all three drag targets from Host->Guest since we can present
- * filenames in any of these forms if an application requests.  However, we
- * only support file drag targets (text/uri-list) from Guest->Host since we
- * can only DnD files across the backdoor.
- */
-#define NR_DRAG_TARGETS                 3
-#define NR_GH_DRAG_TARGETS              1
-
-#define DROPEFFECT_NONE 0
-#define DROPEFFECT_COPY 1
-#define DROPEFFECT_MOVE 2
-#define DROPEFFECT_LINK 4
-
-/*
- * More friendly names for calling DnDFakeXEvents().  This is really ugly but
- * it allows us to keep all of the X fake event code in one place.
- *
- * Operation | showWidget | buttonEvent | buttonPress | moveWindow | coordsProvided
- * ----------+------------+-------------+-------------+------------+---------------
- * G->H Drag |    Yes     |      No     |     n/a     |    Yes     |       No
- * G->H Drop |     No     |     Yes     |   Release   |    Yes     |       No
- * H->G Drag |    Yes     |     Yes     |    Press    |    Yes     |       No
- * H->G Move |     No     |      No     |     n/a     |     No     |      Yes
- * H->G Drop |     No     |     Yes     |   Release   |     No     |      Yes
- * ----------+------------+-------------+-------------+------------+---------------
- */
-#define DnDGHFakeDrag(widget) \
-    DnDFakeXEvents(widget, TRUE, FALSE, FALSE, TRUE, FALSE, 0, 0)
-#define DnDGHFakeDrop(widget) \
-    DnDFakeXEvents(widget, FALSE, TRUE, FALSE, TRUE, FALSE, 0, 0)
-#define DnDHGFakeDrag(widget) \
-    DnDFakeXEvents(widget, TRUE, TRUE, TRUE, TRUE, FALSE, 0, 0)
-#define DnDHGFakeMove(widget, x, y) \
-    DnDFakeXEvents(widget, FALSE, FALSE, FALSE, FALSE, TRUE, x, y)
-#define DnDHGFakeDrop(widget, x, y) \
-    DnDFakeXEvents(widget, FALSE, TRUE, FALSE, FALSE, TRUE, x, y)
-
-#ifdef GTK2
-# define GDKATOM_TO_ATOM(gdkAtom) gdk_x11_atom_to_xatom(gdkAtom)
-#else
-# define GDKATOM_TO_ATOM(gdkAtom) gdkAtom
-#endif
-
-/*
- * Forward Declarations
- */
-static Bool DnDRpcInEnterCB      (char const **result, size_t *resultLen,
-                                  const char *name, const char *args,
-                                  size_t argsSize,void *clientData);
-static Bool DnDRpcInDataSetCB    (char const **result, size_t *resultLen,
-                                  const char *name, const char *args,
-                                  size_t argsSize,void *clientData);
-static Bool DnDRpcInMoveCB       (char const **result, size_t *resultLen,
-                                  const char *name, const char *args,
-                                  size_t argsSize,void *clientData);
-static Bool DnDRpcInDataFinishCB (char const **result, size_t *resultLen,
-                                  const char *name, const char *args,
-                                  size_t argsSize,void *clientData);
-static Bool DnDRpcInDropCB       (char const **result, size_t *resultLen,
-                                  const char *name, const char *args,
-                                  size_t argsSize,void *clientData);
-static Bool DnDRpcInMouseUngrabCB(char const **result, size_t *resultLen,
-                                  const char *name, const char *args,
-                                  size_t argsSize,void *clientData);
-static Bool DnDRpcInGetNextFileCB(char const **result, size_t *resultLen,
-                                  const char *name, const char *args,
-                                  size_t argsSize,void *clientData);
-static Bool DnDRpcInFinishCB     (char const **result, size_t *resultLen,
-                                  const char *name, const char *args,
-                                  size_t argsSize,void *clientData);
-
-/*
- * Gtk DnD specific event/signal callbacks.
- */
-/* For Host->Guest DnD */
-static void DnDGtkBeginCB(GtkWidget *widget, GdkDragContext *dc, gpointer data);
-static void DnDGtkEndCB(GtkWidget *widget, GdkDragContext *dc, gpointer data);
-static void DnDGtkDataRequestCB(GtkWidget *widget, GdkDragContext *dc,
-                                GtkSelectionData *selection_data,
-                                guint info, guint time, gpointer data);
-
-/* For Guest->Host DnD */
-static gboolean DnDGtkDragMotionCB(GtkWidget *widget, GdkDragContext *dc, gint x,
-                                   gint y, guint time, gpointer data);
-static void DnDGtkDragDataReceivedCB(GtkWidget *widget, GdkDragContext *dc,
-                                     gint x, gint y, GtkSelectionData *dragData,
-                                     guint info, guint time, gpointer data);
-static gboolean DnDGtkDragDropCB(GtkWidget *widget, GdkDragContext *dc,
-                                 gint x, gint y, guint time, gpointer data);
-
-/*
- * Utility
- */
-static Bool DnDSendVmxNewFileRoot(char *rpcCmd);
-static Bool DnDFakeXEvents(GtkWidget *widget, Bool showWidget,
-                           Bool buttonEvent, Bool buttonPress,
-                           Bool moveWindow,
-                           Bool coordsProvided, int x, int y);
-static void DnDSendEscapeKey(GtkWidget *mainWnd);
-static INLINE Bool DnDGHDragPending(GtkWidget *widget);
-static INLINE Bool DnDGHXdndDragPending(GtkWidget *widget);
-static INLINE void DnDGHXdndClearPending(GtkWidget *widget);
-static INLINE Bool DnDGHMotifDragPending(GtkWidget *widget);
-static INLINE void DnDGHFileListClear(void);
-static INLINE void DnDGHFileListSet(char *fileList, size_t fileListSize);
-static INLINE Bool DnDGHFileListGetNext(char **fileName, size_t *fileNameSize);
-static INLINE void DnDGHStateInit(GtkWidget *widget);
-static INLINE void DnDHGStateInit(void);
-static INLINE Bool DnDGHCancel(GtkWidget *widget);
-static Bool DnDGHXEventTimeout(void *clientData);
-
-/*
- * Globals
- */
-struct ghState {
-   Bool dragInProgress;
-   Bool ungrabReceived;
-   char *dndFileList;
-   char *dndFileListNext;
-   size_t dndFileListSize;
-   GdkDragContext *dragContext;
-   guint time;
-   Event *event;
-} gGHState;
-static Bool gHGDnDInProgress;
-static Bool gDoneDragging;
-static Bool gHGDataPending;
-static char gDnDData[1024];
-static GdkDragContext *gDragCtx;
-static GtkTargetEntry gTargetEntry[NR_DRAG_TARGETS];
-static GdkAtom gTargetEntryAtom[NR_GH_DRAG_TARGETS];
-static char gFileRoot[DND_MAX_PATH];
-static size_t gFileRootSize;
-static size_t gDnDDataSize;
-static Bool gUnity;
-
-/*
- * From vmwareuserInt.h
- */
-RpcIn     *gRpcIn;
-Display   *gXDisplay;
-Window     gXRoot;
-
-
-/*
- * Host->Guest RPC callback implementations
- */
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DnDRpcInEnterCB --
- *
- *       For Host->Guest operations only.
- *       User has dragged something over this guest's MKS window
- *
- * Results:
- *       TRUE on success, FALSE otherwise
- *
- * Side effects:
- *      Some GdkEvents are generated which will "drag" the mouse. A directory
- *       is created.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-DnDRpcInEnterCB(char const **result,     // OUT
-                size_t *resultLen,       // OUT
-                const char *name,        // IN
-                const char *args,        // IN
-                size_t argsSize,         // Ignored
-                void *clientData)        // IN
-{
-   char *numFormats;
-   char *pFormat;
-   unsigned int index = 0;
-   int nFormats;
-   int i;
-   GtkWidget *mainWnd;
-
-   Debug("Got DnDRpcInEnterCB\n");
-   mainWnd = GTK_WIDGET(clientData);
-   if (mainWnd == NULL) {
-      return RpcIn_SetRetVals(result, resultLen,
-                              "bad clientData passed to callback", FALSE);
-   }
-
-   if (!DnD_BlockIsReady(&gBlockCtrl)) {
-      Debug("DnDRpcInEnterCB: cannot allow H->G DnD without vmblock.\n");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "blocking file system unavailable", FALSE);
-   }
-
-   numFormats = StrUtil_GetNextToken(&index, args, " ");
-   if (!numFormats) {
-      Debug("DnDRpcInEnterCB: Failed to parse numformats\n");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "must specify number of formats", FALSE);
-   }
-
-   /* Skip whitespace character. */
-   index++;
-
-   nFormats = atoi(numFormats);
-   free(numFormats);
-
-   for (i = 0; i < nFormats; i++) {
-      pFormat = StrUtil_GetNextToken(&index, args, ",");
-
-      if (!pFormat) {
-         Debug("DnDRpcInEnterCB: Failed to parse format list\n");
-         return RpcIn_SetRetVals(result, resultLen,
-                                 "Failed to read format list", FALSE);
-      } else {
-         /*
-          * TODO: check that formats are ok for us to handle. For now, this is
-          * ok since there should only be a CF_HDROP. But, we really should figure
-          * out a much more cross-platform format scheme
-          */
-         free(pFormat);
-      }
-   }
-
-   if (!DnDHGFakeDrag(mainWnd)) {
-      Debug("DnDRpcInEnterCB: Failed to fake X events\n");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "failed to fake drag", FALSE);
-   }
-
-   RpcIn_SetRetVals(result, resultLen, "", TRUE);
-   RpcOut_sendOne(NULL, NULL, "dnd.feedback copy");
-   Debug("DnDRpcInEnterCB finished\n");
-   return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DnDRpcInDataSetCB --
- *
- *       For Host->Guest operations only.
- *       Host is sending data from a DnD operation.
- *
- * Results:
- *       TRUE on success, FALSE otherwise.
- *
- * Side effects:
- *      None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-DnDRpcInDataSetCB(char const **result,  // OUT
-                  size_t *resultLen,    // OUT
-                  const char *name,     // IN
-                  const char *args,     // IN
-                  size_t argsSize,      // IN: Size of args
-                  void *clientData)     // Ignored
-{
-   char blockDir[DND_MAX_PATH];
-   char *perDnDDir = NULL;
-   char *format;
-   char  *data;
-   unsigned int index = 0;
-   size_t dataSize;
-   char *retStr;
-   Bool ret = FALSE;
-
-   Debug("DnDRpcInDataSetCB: enter\n");
-
-   if (!DnD_BlockIsReady(&gBlockCtrl)) {
-      Debug("DnDRpcInDataSetCB: blocking file system not available.\n");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "blocking file system not available", FALSE);
-   }
-
-   /* Parse the data type & value string. */
-   format = StrUtil_GetNextToken(&index, args, " ");
-   if (!format) {
-      Debug("DnDRpcInDataSetCB: Failed to parse format\n");
-      return RpcIn_SetRetVals(result, resultLen, "need format", FALSE);
-   }
-
-   index++; /* Ignore leading space before data. */
-   dataSize = argsSize - index;
-   data = Util_SafeMalloc(dataSize);
-   memcpy(data, args + index, dataSize);
-
-   Debug("DnDRpcInDataSetCB: Received data from host: (%s) [%s] (%"FMTSZ"u)\n",
-         format, CPName_Print(data, dataSize), dataSize);
-
-   /*
-    * Here we take the last component of the actual file root, which is
-    * a temporary directory for this DnD operation, and append it to the mount
-    * point for vmblock.  This is where we want the target application to
-    * access the file since it will enable vmblock to block that application's
-    * progress if necessary.
-    */
-   perDnDDir = DnD_GetLastDirName(gFileRoot);
-   if (!perDnDDir) {
-      Debug("DnDRpcInDataSetCB: cannot obtain dirname of root.\n");
-      retStr = "error obtaining dirname of root";
-      goto out;
-   }
-
-   if (strlen(gBlockCtrl.blockRoot) +
-       (sizeof DIRSEPS - 1) * 2 + strlen(perDnDDir) >= sizeof blockDir) {
-      Debug("DnDRpcInDataSetCB: blocking directory path too large.\n");
-      retStr = "blocking directory path too large";
-      goto out;
-   }
-
-   Str_Sprintf(blockDir, sizeof blockDir,
-               "%s" DIRSEPS "%s" DIRSEPS, gBlockCtrl.blockRoot, perDnDDir);
-
-   /* Add the file root to the relative paths received from host */
-   if (!DnD_PrependFileRoot(blockDir, &data, &dataSize)) {
-      Debug("DnDRpcInDataSsetCB: error prepending guest file root\n");
-      retStr = "error prepending file root";
-      goto out;
-   }
-   if (dataSize + 1 > sizeof gDnDData) {
-      Debug("DnDRpcInDataSetCB: data too large\n");
-      retStr = "data too large";
-      goto out;
-   }
-
-   memcpy(gDnDData, data, dataSize + 1);
-   gDnDDataSize = dataSize;
-   Debug("DnDRpcInDataSetCB: prepended file root [%s] (%"FMTSZ"u)\n",
-         CPName_Print(gDnDData, gDnDDataSize), gDnDDataSize);
-
-   retStr = "";
-   ret = TRUE;
-
-out:
-   free(format);
-   free(data);
-   free(perDnDDir);
-   return RpcIn_SetRetVals(result, resultLen, retStr, ret);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DnDRpcInMoveCB --
- *
- *       For Host->Guest operations only.
- *       Host user is dragging data over this guest's MKS window
- *
- * Results:
- *       TRUE on success, FALSE otherwise.
- *
- * Side effects:
- *      Send a gdk event that "moves" the mouse.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-DnDRpcInMoveCB(char const **result,     // OUT
-               size_t *resultLen,       // OUT
-               const char *name,        // IN
-               const char *args,        // IN
-               size_t argsSize,         // Ignored
-               void *clientData)        // IN: pointer to mainWnd
-{
-   GtkWidget *mainWnd;
-   char *sXCoord;
-   char *sYCoord;
-   unsigned int index = 0;
-   int xCoord, yCoord;
-
-   mainWnd = GTK_WIDGET(clientData);
-   if (mainWnd == NULL) {
-      return RpcIn_SetRetVals(result, resultLen,
-                              "bad clientData passed to callback", FALSE);
-   }
-
-   sXCoord = StrUtil_GetNextToken(&index, args, " ");
-   sYCoord = StrUtil_GetNextToken(&index, args, " ");
-
-   if (!sXCoord || !sYCoord) {
-      Debug("DnDRpcInMove: Failed to parse coords\n");
-      free(sXCoord);
-      free(sYCoord);
-      return RpcIn_SetRetVals(result, resultLen,
-                              "error reading mouse move data", FALSE);
-   }
-
-   xCoord = atoi(sXCoord);
-   yCoord = atoi(sYCoord);
-
-   free(sXCoord);
-   free(sYCoord);
-
-   /* Fake a mouse move */
-   if (!DnDHGFakeMove(mainWnd, xCoord, yCoord)) {
-      Debug("DnDRpcInMove: Failed to fake mouse movement\n");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "failed to move mouse", FALSE);
-   }
-
-   return RpcIn_SetRetVals(result, resultLen, "", TRUE);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DnDRpcInDataFinishCB --
- *
- *       For Host->Guest operations only.
- *       Host has finished transferring DnD data to the guest. We do any post
- *       H->G operation cleanup here, like removing the block on the staging
- *       directory, picking a new file root, and informing the host of the new
- *       root.
- *
- * Results:
- *       TRUE on success, FALSE otherwise
- *
- * Side effects:
- *      None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-DnDRpcInDataFinishCB(char const **result,   // OUT
-                     size_t *resultLen,     // OUT
-                     const char *name,      // IN
-                     const char *args,      // IN
-                     size_t argsSize,       // Ignored
-                     void *clientData)      // Ignored
-{
-   unsigned int index = 0;
-   char *state;
-
-   Debug("DnDRpcInDataFinishCB: enter\n");
-
-   state = StrUtil_GetNextToken(&index, args, " ");
-   if (!state) {
-      Debug("DnDRpcInDataFinishCB: could not get dnd finish state.\n");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "could not get dnd finish state", FALSE);
-   }
-
-   /* 
-    * If the guest doesn't support vmblock, we'll have bailed out of 
-    * DndRpcInDropCB before setting gHGDataPending. Thus, it doesn't make sense
-    * to pop a warning here, but let's keep the message around just in case 
-    * there can be a failure worth hearing about.
-    */
-   if (!gHGDataPending) {
-      Debug("DnDRpcInDataFinishCB: expected gHGDataPending to be set.\n");
-   }
-
-   gHGDataPending = FALSE;
-
-   /*
-    * The host will send us "success" or "error", depending on whether the
-    * transfer finished successfully.  In either case we remove the pending
-    * block, but in the "error" case we also need to delete all the files so
-    * the destination application doesn't access the partially copied files and
-    * mistake them for a successful drop.
-    */
-   if (strcmp(state, "success") != 0) {
-      /* On any non-success input, delete the files. */
-      DnD_DeleteStagingFiles(gFileRoot, FALSE);
-   }
-
-   free(state);
-
-   if (DnD_BlockIsReady(&gBlockCtrl) &&
-       !gBlockCtrl.RemoveBlock(gBlockCtrl.fd, gFileRoot)) {
-      Warning("DnDRpcInDataFinishCB: could not remove block on %s\n",
-              gFileRoot);
-   }
-
-   /* Pick a new file root and send that to the host for the next DnD. */
-   if (!DnDSendVmxNewFileRoot("dnd.setGuestFileRoot")) {
-      Debug("DnDRpcInDataFinishCB: Failed to send dnd.setGuestFileRoot "
-            "message to host\n");
-      return RpcIn_SetRetVals(result, resultLen, "could not send guest root", FALSE);
-   }
-
-   return RpcIn_SetRetVals(result, resultLen, "", TRUE);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DnDRpcInDropCB --
- *
- *       For Host->Guest operations only.
- *       Host user has dropped data over this guest's MKS window.  We add
- *       a block on the staging directory then send a fake mouse release to
- *       invoke the drop completion (from Gtk's point of view).
- *
- * Results:
- *       TRUE on success, FALSE otherwise.
- *
- * Side effects:
- *      None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-DnDRpcInDropCB(char const **result,   // OUT
-               size_t *resultLen,     // OUT
-               const char *name,      // IN
-               const char *args,      // IN
-               size_t argsSize,       // Ignored
-               void *clientData)      // IN: Gtk window widget
-{
-   GtkWidget *mainWnd;
-   char *sXCoord;
-   char *sYCoord;
-   unsigned int index = 0;
-   int xCoord, yCoord;
-
-   Debug("DnDRpcInDropCB: enter\n");
-
-   gDoneDragging = TRUE;
-
-   mainWnd = GTK_WIDGET(clientData);
-   if (mainWnd == NULL) {
-      return RpcIn_SetRetVals(result, resultLen,
-                              "bad clientData passed to callback", FALSE);
-   }
-
-   sXCoord = StrUtil_GetNextToken(&index, args, " ");
-   sYCoord = StrUtil_GetNextToken(&index, args, " ");
-
-   if (!sXCoord || !sYCoord) {
-      Debug("DnDRpcInDropCB: Failed to parse coords\n");
-      free(sXCoord);
-      free(sYCoord);
-      return RpcIn_SetRetVals(result, resultLen,
-                              "must specify drop coordinates", FALSE);
-   }
-
-   xCoord = atoi(sXCoord);
-   yCoord = atoi(sYCoord);
-
-   free(sXCoord);
-   free(sYCoord);
-
-   Debug("DnDRpcInDropCB: Received drop notification at (%d,%d)\n",
-         xCoord, yCoord);
-
-   /*
-    * Add a block on the guest file root, warp the pointer, then fake the mouse
-    * release.  Make sure we'll succeed before modifying any mouse state in the
-    * guest.
-    */
-   if (!DnD_BlockIsReady(&gBlockCtrl)) {
-      /*
-       * We shouldn't get here since DnDRpcInEnterCB() checks this, but we'll
-       * check rather than ASSERT just in case.
-       */
-      return RpcIn_SetRetVals(result, resultLen,
-                              "blocking file system unavailable", FALSE);
-   }
-
-   if (!gBlockCtrl.AddBlock(gBlockCtrl.fd, gFileRoot)) {
-      return RpcIn_SetRetVals(result, resultLen, "could not add block", FALSE);
-   }
-
-   /* Update state before causing faking any mouse or keyboard changes. */
-   gHGDataPending = TRUE;
-
-
-   if (!DnDHGFakeDrop(mainWnd, xCoord, yCoord)) {
-      Debug("DnDRpcInDropCB: failed to fake drop\n");
-      return RpcIn_SetRetVals(result, resultLen, "failed to fake drop", FALSE);
-   }
-
-   return RpcIn_SetRetVals(result, resultLen, "", TRUE);
-}
-
-
-/*
- * Guest->Host RPC callback implementations
- */
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDRpcInMouseUngrabCB --
- *
- *    For Guest->Host operations only.
- *
- *    Called when a mouse ungrab is attempted with the mouse button down.  When
- *    the MKS sees mouse movements outside of the clip (the viewable portion of
- *    the guest's display) while a mouse button is down, this function is
- *    called so we can inform the MKS whether to allow the ungrab (and start
- *    a DnD if one is pending).
- *
- * Results:
- *    TRUE on success, FALSE on failure.
- *
- * Side effects:
- *    The GDK window is moved and resized, and the mouse is moved over it.
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-DnDRpcInMouseUngrabCB(char const **result,      // OUT
-                      size_t *resultLen,        // OUT
-                      const char *name,         // IN
-                      const char *args,         // IN
-                      size_t argsSize,          // Ignored
-                      void *clientData)         // IN
-{
-   unsigned int index = 0;
-   GtkWidget *mainWnd;
-   int32 xPos;
-   int32 yPos;
-
-   Debug("Got DnDRpcInMouseUngrabCB\n");
-   mainWnd = GTK_WIDGET(clientData);
-   if (mainWnd == NULL) {
-      Warning("DnDRpcInMouseUngrabCB: invalid clientData\n");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "bad clientData passed to callback", FALSE);
-   }
-
-   /*
-    * If there is already a DnD or copy/paste in progress (including the file
-    * transfer), don't allow another.
-    */
-   if (gHGDataPending || gGHState.dragInProgress || CopyPaste_InProgress()) {
-      RpcOut_sendOne(NULL, NULL, "dnd.notpending");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "dnd already in progress", FALSE);
-   }
-
-   if (!StrUtil_GetNextIntToken(&xPos, &index, args, " ")) {
-      Warning("DnDRpcInMouseUngrabCB: could not parse x coordinate\n");
-      RpcOut_sendOne(NULL, NULL, "dnd.notpending");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "Failed to parse x coordinate", FALSE);
-   }
-
-   if (!StrUtil_GetNextIntToken(&yPos, &index, args, " ")) {
-      Warning("DnDRpcInMouseUngrabCB: could not parse y coordinate\n");
-      RpcOut_sendOne(NULL, NULL, "dnd.notpending");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "Failed to parse y coordinate", FALSE);
-   }
-
-   Debug("DnDRpcInMouseUngrabCB: Received (%d,%d)\n", xPos, yPos);
-
-   /*
-    * If there is no DnD pending, inform the host so the MKS can start sending
-    * mouse packets again.
-    */
-   if (!DnDGHDragPending(mainWnd)) {
-      RpcOut_sendOne(NULL, NULL, "dnd.notpending");
-      return RpcIn_SetRetVals(result, resultLen, "DnD not pending", TRUE);
-   }
-
-   /* The host only gives us coordinates within our screen */
-   ASSERT(xPos >= 0);
-   ASSERT(yPos >= 0);
-
-   /*
-    * Fake mouse movements over the window to try and generate a "drag_motion"
-    * signal from GTK.  If a drag is pending, that signal will be sent to our
-    * widget and DnDGtkDragMotionCB will be invoked to start the DnD
-    * operation.
-    */
-   if (!DnDGHFakeDrag(mainWnd)) {
-      Warning("DnDRpcInMouseUngrabCB: could not fake X events\n");
-      RpcOut_sendOne(NULL, NULL, "dnd.notpending");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "error faking X events", FALSE);
-   }
-
-   /*
-    * Add event to fire and hide our widget if a DnD is not pending.  Note that
-    * this is here in case our drag pending heuristic for Xdnd and Motif does
-    * not encompass all cases, or if the X events we generate don't cause the
-    * "drag_motion" for some other reason.
-    */
-   gGHState.event = EventManager_Add(gEventQueue, RPCIN_POLL_TIME * 100,
-                                     DnDGHXEventTimeout, mainWnd);
-   if (!gGHState.event) {
-      Warning("DnDRpcInMouseUngrabCB: could not create event\n");
-      RpcOut_sendOne(NULL, NULL, "dnd.notpending");
-      return RpcIn_SetRetVals(result, resultLen,
-                              "could not create timeout event", FALSE);
-   }
-
-   gGHState.dragInProgress = FALSE;
-   gGHState.ungrabReceived = TRUE;
-
-   Debug("DnDRpcInMouseUngrabCB finished\n");
-   return RpcIn_SetRetVals(result, resultLen, "", TRUE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDRpcInGetNextFileCB --
- *
- *    For Guest->Host operations only.
- *
- *    Invoked when the host is compiling its list of files to copy from the
- *    guest.  Here we provide the path of the next file in our Guest->Host file
- *    list in guest path format (for display purposes) and CPName format (for
- *    file copy operation).
- *
- * Results:
- *    TRUE on success, FALSE on failure.
- *
- * Side effects:
- *    Iterator pointer within file list of GH state is iterated to next list
- *    entry (through call to DnDGHFileListGetNext()).
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-DnDRpcInGetNextFileCB(char const **result,      // OUT
-                      size_t *resultLen,        // OUT
-                      const char *name,         // IN
-                      const char *args,         // IN
-                      size_t argsSize,          // Ignored
-                      void *clientData)         // IN
-{
-   static char resultBuffer[DND_MAX_PATH];
-   char *fileName;
-   size_t fileNameSize;
-   uint32 cpNameSize;
-   GtkWidget *mainWnd;
-   Bool res;
-
-   mainWnd = GTK_WIDGET(clientData);
-   if (mainWnd == NULL) {
-      DnDGHCancel(NULL);
-      return RpcIn_SetRetVals(result, resultLen,
-                              "bad clientData passed to callback", FALSE);
-   }
-
-   /*
-    * Retrieve a pointer to the next filename and its size from the list stored
-    * in the G->H DnD state.  Note that fileName should not be free(3)d here
-    * since an additional copy is not allocated.
-    */
-   res = DnDGHFileListGetNext(&fileName, &fileNameSize);
-
-   if (!res) {
-      Warning("DnDRpcInGetNextFileCB: error retrieving file name\n");
-      DnDGHCancel(mainWnd);
-      return RpcIn_SetRetVals(result, resultLen, "error getting file", FALSE);
-   }
-
-   if (!fileName) {
-      /* There are no more files to send */
-      Debug("DnDRpcInGetNextFileCB: reached end of Guest->Host file list\n");
-      return RpcIn_SetRetVals(result, resultLen, "|end|", TRUE);
-   }
-
-   if (fileNameSize + 1 + fileNameSize > sizeof resultBuffer) {
-      Warning("DnDRpcInGetNextFileCB: filename too large (%"FMTSZ"u)\n", fileNameSize);
-      DnDGHCancel(mainWnd);
-      return RpcIn_SetRetVals(result, resultLen, "filename too large", FALSE);
-   }
-
-   /*
-    * Construct a reply message of the form:
-    * <file name in guest format><NUL><filename in CPName format>
-    */
-   memcpy(resultBuffer, fileName, fileNameSize);
-   resultBuffer[fileNameSize] = '\0';
-
-   cpNameSize = CPNameUtil_ConvertToRoot(fileName,
-                                         sizeof resultBuffer - (fileNameSize + 1),
-                                         resultBuffer + fileNameSize + 1);
-   if (cpNameSize < 0) {
-      Warning("DnDRpcInGetNextFileCB: could not convert to CPName\n");
-      DnDGHCancel(mainWnd);
-      return RpcIn_SetRetVals(result, resultLen,
-                              "error on CPName conversion", FALSE);
-   }
-
-   /* Set manually because RpcIn_SetRetVals() assumes no NUL characters */
-   *result = resultBuffer;
-   *resultLen = fileNameSize + 1 + cpNameSize;
-
-   Debug("DnDRpcInGetNextFileCB: [%s] (%"FMTSZ"u)\n",
-         CPName_Print(*result, *resultLen), *resultLen);
-
-   return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDRpcInFinishCB --
- *
- *    For Guest->Host operations only.
- *
- *    Invoked when host side of DnD operation has finished.
- *
- * Results:
- *    TRUE on success, FALSE on failure.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-DnDRpcInFinishCB(char const **result,      // OUT
-                 size_t *resultLen,        // OUT
-                 const char *name,         // IN
-                 const char *args,         // IN
-                 size_t argsSize,          // Ignored
-                 void *clientData)         // IN
-{
-   GtkWidget *mainWnd;
-   char *effect = NULL;
-   unsigned int index = 0;
-   char *retStr;
-   Bool ret = FALSE;
-
-   mainWnd = GTK_WIDGET(clientData);
-   if (mainWnd == NULL) {
-      retStr = "bad clientData passed to callback";
-      goto exit;
-   }
-
-   effect = StrUtil_GetNextToken(&index, args, " ");
-   if (!effect) {
-      Warning("DnDRpcInFinishCB: no drop effect provided\n");
-      retStr = "drop effect not provided";
-      goto exit;
-   }
-
-   if (strcmp(effect, "cancel") == 0) {
-      DnDSendEscapeKey(mainWnd);
-      DnDGHCancel(mainWnd);
-   } else {
-      /*
-       * The drop happened on the host.  Fake X events such that our window is
-       * placed at the mouse's coordinates and raised, then fake a button
-       * release on the window.  This causes us to get a "drag_drop" signal
-       * from GTK on our widget.
-       */
-      if (!DnDGHFakeDrop(mainWnd)) {
-         Warning("DnDRpcInFinishCB: could not fake X events\n");
-         retStr = "error faking X events";
-         goto exit;
-      }
-
-      gGHState.event = EventManager_Add(gEventQueue, RPCIN_POLL_TIME * 10,
-                                           DnDGHXEventTimeout, mainWnd);
-      if (!gGHState.event) {
-         Warning("DnDRpcInFinishCB: could not create event\n");
-         retStr = "could not create timeout event";
-         goto exit;
-      }
-   }
-
-   retStr = "";
-   ret = TRUE;
-
-exit:
-   if (!ret) {
-      DnDGHCancel(mainWnd);
-   }
-
-   free(effect);
-   gGHState.dragInProgress = FALSE;
-   return RpcIn_SetRetVals(result, resultLen, retStr, ret);
-}
-
-
-/*
- * Host->Guest (drop source) Gtk callback implementations
- */
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DnDGtkBeginCB --
- *
- *       "drag_begin" signal handler for GTK.  This signal will be received
- *       after the fake mouse press sent in DnDRpcInEnterCB() is performed.
- *       Here we simply initialize our state variables.
- *
- * Results:
- *       None
- *
- * Side effects:
- *      None
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-DnDGtkBeginCB(GtkWidget *widget,   // IN: the widget under the drag
-              GdkDragContext *dc,  // IN: the drag context maintained by gdk
-              gpointer data)       // IN: unused
-{
-   GtkWidget *mainWnd = GTK_WIDGET(data);
-
-   Debug("DnDGtkBeginCB: entry\n");
-
-   if ((widget == NULL) || (mainWnd == NULL) || (dc == NULL)) {
-      return;
-   }
-
-   gHGDnDInProgress = TRUE;
-   gDoneDragging = FALSE;
-   gHGDataPending = FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DnDGtkEndCB --
- *
- *       "drag_end" signal handler for GTK. This is called when a drag and drop has
- *       completed. So this function is the last one to be called in any given DnD
- *       operation.
- *
- * Results:
- *       None
- *
- * Side effects:
- *      None
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-DnDGtkEndCB(GtkWidget *widget,   // IN: the widget under the drag
-            GdkDragContext *dc,  // IN: the drag context maintained by gdk
-            gpointer data)       // IN: unused
-{
-
-   GtkWidget *mainWnd = GTK_WIDGET(data);
-
-   Debug("DnDGtkEndCB: enter\n");
-
-   if (mainWnd == NULL || dc == NULL) {
-      return;
-   }
-
-   /*
-    * Do not set gHGDataPending to FALSE since DnD operation completes before
-    * the data transfer.
-    */
-   gDoneDragging = FALSE;
-   gHGDnDInProgress = FALSE;
-
-   RpcOut_sendOne(NULL, NULL, "dnd.finish %d", DROPEFFECT_COPY);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DnDGtkDataRequestCB --
- *       DnD "drag_data_get" handler, for handling requests for DnD data on the
- *       specified widget. This function is called when there is need for DnD data
- *       on thesource, so this function is responsible for setting up the dynamic
- *       data exchange buffer and sending it out.
- *
- * Results:
- *       None
- *
- * Side effects:
- *      Data is avaiable to drop target.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-DnDGtkDataRequestCB(GtkWidget *widget,                // IN
-                    GdkDragContext *dc,               // IN
-                    GtkSelectionData *selection_data, // IN/OUT: buffer for the data
-                    guint info,                       // IN: the requested fo the data
-                    guint time,                       // IN: unused
-                    gpointer data)                    // IN: unused
-{
-   const char *begin;
-   const char *end;
-   const char *next;
-   const char *pre;
-   const char *post;
-   size_t preLen;
-   size_t postLen;
-   int len;
-   Bool insertSpace;
-   char *text = NULL;
-   size_t textLen = 1;
-
-   Debug("DnDGtkDataRequestCB: enter\n");
-
-   if ((widget == NULL) || (dc == NULL) || (selection_data == NULL)) {
-      Debug("DnDGtkDataRequestCB: Error, widget or dc or selection_data is invalid\n");
-      return;
-   }
-
-   /* Do nothing if we have not finished dragging yet */
-   if (!gDoneDragging) {
-      Debug("DnDGtkDataRequestCB: not done dragging yet\n");
-      return;
-   }
-
-   /* Setup the format string components */
-   switch (info) {
-   case DRAG_TARGET_INFO_URI_LIST:      /* text/uri-list */
-      pre = DND_URI_LIST_PRE;
-      preLen = sizeof DND_URI_LIST_PRE - 1;
-      post = DND_URI_LIST_POST;
-      postLen = sizeof DND_URI_LIST_POST - 1;
-      insertSpace = FALSE;
-      break;
-   case DRAG_TARGET_INFO_TEXT_PLAIN:    /* text/plain */
-      pre = DND_TEXT_PLAIN_PRE;
-      preLen = sizeof DND_TEXT_PLAIN_PRE - 1;
-      post = DND_TEXT_PLAIN_POST;
-      postLen = sizeof DND_TEXT_PLAIN_POST - 1;
-      insertSpace = TRUE;
-      break;
-   case DRAG_TARGET_INFO_STRING:        /* STRING */
-      pre = DND_STRING_PRE;
-      preLen = sizeof DND_STRING_PRE - 1;
-      post = DND_STRING_POST;
-      postLen = sizeof DND_STRING_POST - 1;
-      insertSpace = TRUE;
-      break;
-   default:
-      Log("DnDGtkDataRequestCB: invalid drag target info\n");
-      return;
-   }
-
-
-   /*
-    * Set begin to first non-NUL character and end to last NUL character to
-    * prevent errors in calling CPName_GetComponent().
-    */
-   for(begin = gDnDData; *begin == '\0'; begin++)
-      ;
-   end = CPNameUtil_Strrchr(gDnDData, gDnDDataSize + 1, '\0');
-   ASSERT(end);
-
-   /* Build up selection data */
-   while ((len = CPName_GetComponent(begin, end, &next)) != 0) {
-      const size_t origTextLen = textLen;
-      Bool freeBegin = FALSE;
-
-      if (len < 0) {
-         Log("DnDGtkDataRequestCB: error getting next component\n");
-         if (text) {
-            free(text);
-         }
-         return;
-      }
-
-      /*
-       * A URI list will expect the provided path to be escaped.  If we cannot
-       * escape the path for some reason we just use the unescaped version and
-       * hope that it works.
-       */
-      if (info == DRAG_TARGET_INFO_URI_LIST) {
-         size_t newLen;
-         char *escapedComponent;
-         int escIndex;
-         int bytesToEsc[256] = { 0, };
-
-         /* We escape the following characters based on RFC 1630. */
-         bytesToEsc['#'] = 1;
-         bytesToEsc['?'] = 1;
-         bytesToEsc['*'] = 1;
-         bytesToEsc['!'] = 1;
-         bytesToEsc['%'] = 1;  /* Escape character */
-
-         /* Escape non-ASCII characters so we can pass UTF-8 filenames */
-         for (escIndex = 0x80; escIndex < 0x100; escIndex++) {
-            bytesToEsc[escIndex] = 1;
-         }
-
-         escapedComponent = Escape_Do('%', bytesToEsc, begin, len, &newLen);
-         if (escapedComponent) {
-            begin = escapedComponent;
-            len = newLen;
-            freeBegin = TRUE;
-         }
-      }
-
-      /*
-       * Append component.  NUL terminator was accounted for by initializing
-       * textLen to one above.
-       */
-      textLen += preLen + len + postLen + (insertSpace ? 1 : 0);
-      text = Util_SafeRealloc(text, textLen);
-      Str_Snprintf(text + origTextLen - 1,
-                   textLen - origTextLen + 1,
-                   "%s%s%s", pre, begin, post);
-
-      if (insertSpace && next != end) {
-         ASSERT(textLen - 2 >= 0);
-         text[textLen - 2] = ' ';
-         text[textLen - 1] = '\0';
-      }
-
-      if (freeBegin) {
-         free((void *)begin);
-      }
-
-      /* Iterate to next component */
-      begin = next;
-   }
-
-   /*
-    * Send out the data using the selection system. When sending a string, GTK will
-    * ensure that a null terminating byte is added to the end so we do not need to
-    * add it. GTK also copies the data so the original will never be modified.
-    */
-   Debug("DnDGtkDataRequestCB: calling gtk_selection_data_set with [%s]\n", text);
-   gtk_selection_data_set(selection_data, selection_data->target,
-                          8, /* 8 bits per character. */
-                          text, textLen);
-   free(text);
-}
-
-
-/*
- * Guest->Host (drop target) Gtk callback implementations
- */
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDGtkDragMotionCB --
- *
- *    "drag_motion" signal handler for GTK.  This is invoked each time the
- *    mouse moves over the drag target (destination) window when a DnD is
- *    pending.
- *
- * Results:
- *    TRUE on success, FALSE on failure.
- *
- * Side effects:
- *    RPC messages are sent to the host to proxy the DnD over.
- *
- *----------------------------------------------------------------------------
- */
-
-static gboolean
-DnDGtkDragMotionCB(GtkWidget *widget,    // IN: target widget
-                   GdkDragContext *dc,   // IN: the GDK drag context
-                   gint x,               // IN: x position of mouse
-                   gint y,               // IN: y position of mouse
-                   guint time,           // IN: time of event
-                   gpointer data)        // IN: our private data
-{
-   GdkAtom commonTarget = 0;
-   Bool found = FALSE;
-   uint32 i;
-
-   ASSERT(widget);
-   ASSERT(widget == data);
-   ASSERT(dc);
-
-   Debug("DnDGtkDragMotionCB: entry (x=%d, y=%d, time=%d)\n", x, y, time);
-
-   /*
-    * We'll get a number of these and should only carry on these operations on
-    * the first one.
-    *
-    * XXX Unity mode needs to know if there is a g->h->g dnd operation by
-    * detecting if the mouse has left the detection window. This code is
-    * currently not in the guest and should be ported from the host.
-    */
-   if (gGHState.dragInProgress && !gUnity) {
-      Debug("DnDGtkDragMotionCB: drag already in progress\n");
-      return FALSE;
-   }
-
-   /*
-    * Sometimes (rarely) real user mouse movements will trigger "drag_motion"
-    * signals after we have already handled them.  Prevent resetting the data
-    * and trying to start a new DnD operation.
-    */
-   if (!gGHState.ungrabReceived && !gUnity) {
-      Debug("DnDGtkDragMotionCB: extra drag motion without ungrab\n");
-      return FALSE;
-   }
-
-   gGHState.ungrabReceived = FALSE;
-
-   /* Remove event that hides our widget out of band from the DnD protocol. */
-   if (gGHState.event) {
-      Debug("DnDGtkDragMotionCB: removed pending event\n");
-      EventManager_Remove(gGHState.event);
-      gGHState.event = NULL;
-   }
-
-   /*
-    * Note that gdk_drag_status() is called for us by GTK since we passed in
-    * GTK_DEST_DEFAULT_MOTION to gtk_drag_dest_set().  We'd handle it
-    * ourselves, but GTK 1.2.10 has a "bug" that requires us to provide this
-    * flag to get drag_leave and drag_drop signals.
-    */
-
-   /*
-    * We need to try and find a common target format with the list of formats
-    * offered by the drag source.  This list is stored in the drag context's
-    * targets field, and each list member's data variable is a GdkAtom.  We
-    * translated our supported targets into GdkAtoms in gTargetEntryAtom at
-    * initialization.  Note that the GdkAtom value is an index into a table of
-    * strings maintained by the X server, so if they are equivalent then
-    * a common mime type is found.
-    */
-   for (i = 0; i < ARRAYSIZE(gTargetEntryAtom) && !found; i++) {
-      GList *currContextTarget = dc->targets;
-
-      while (currContextTarget) {
-         if (gTargetEntryAtom[i] == (GdkAtom)currContextTarget->data) {
-            commonTarget = gTargetEntryAtom[i];
-            found = TRUE;
-            break;
-         }
-         currContextTarget = currContextTarget->next;
-      }
-   }
-
-   if (!found) {
-      Warning("DnDGtkDragMotionCB: could not find a common target format\n");
-      DnDGHCancel(widget);
-      return FALSE;
-   }
-
-   /*
-    * Request the data.  A "drag_data_received" signal will be sent to widget
-    * (that's us) upon completion.
-    */
-   gtk_drag_get_data(widget, dc, commonTarget, time);
-
-
-   gGHState.dragInProgress = TRUE;
-   return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDGtkDragDataReceivedCB --
- *
- *    "drag_data_received" signal handler for GTK.  Invoked when the data
- *    requested by a gtk_drag_get_data() call is ready.
- *
- *    This function actually begins the drag operation with the host by first
- *    setting the data ("dnd.data.set" RPC command) and then starting the DnD
- *    ("dnd.enter" RPC command).
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-DnDGtkDragDataReceivedCB(GtkWidget *widget,          // IN
-                         GdkDragContext *dc,         // IN
-                         gint x,                     // IN
-                         gint y,                     // IN
-                         GtkSelectionData *dragData, // IN
-                         guint info,                 // IN
-                         guint time,                 // IN
-                         gpointer data)              // IN
-{
-   const char rpcHeader[] = "dnd.data.set CF_HDROP ";
-   const size_t rpcHeaderSize = sizeof rpcHeader - 1;
-   char *rpcBody = NULL;
-   size_t rpcBodySize = 0;
-   char *rpc;
-   size_t rpcSize;
-
-
-   Debug("DnDGtkDragDataReceivedCB: entry\n");
-
-   if (dragData->length < 0) {
-      Warning("DnDGtkDragDataReceivedCB: received length < 0 error\n");
-      goto error;
-   }
-
-   gGHState.dragContext = dc;
-   gGHState.time = time;
-
-   /*
-    * Construct the body of the RPC message and our Guest->Host file list.
-    */
-   if (dragData->target == gTargetEntryAtom[DRAG_TARGET_INFO_URI_LIST]) {
-      char *currName;
-      size_t currSize;
-      size_t index = 0;
-      char *ghFileList = NULL;
-      size_t ghFileListSize = 0;
-
-      Debug("DnDGtkDragDataReceivedCB: uri-list [%s]\n", dragData->data);
-
-      /*
-       * Get the the full filenames and last components from the URI list.  The
-       * body of the RPC message will be these last components delimited with
-       * NUL characters; the Guest->Host file list will be the full paths
-       * delimited by NUL characters.
-       */
-      while ((currName = DnD_UriListGetNextFile(dragData->data,
-                                                &index,
-                                                &currSize))) {
-         size_t lastComponentSize;
-         char *lastComponentStart;
-
-         /* Append current filename to Guest->Host list */
-         ghFileList = Util_SafeRealloc(ghFileList,
-                                       ghFileListSize + currSize + 1);
-         memcpy(ghFileList + ghFileListSize, currName, currSize);
-         ghFileListSize += currSize;
-         ghFileList[ghFileListSize] = '\0';
-         ghFileListSize++;
-
-         /* Append last component to RPC body */
-         lastComponentStart = CPNameUtil_Strrchr(currName, currSize, DIRSEPC);
-         if (!lastComponentStart) {
-            /*
-             * This shouldn't happen since filenames are absolute, but handle
-             * it as if the file name is the last component
-             */
-            lastComponentStart = currName;
-         } else {
-            /* Skip the last directory separator */
-            lastComponentStart++;
-         }
-
-         lastComponentSize = currName + currSize - lastComponentStart;
-         rpcBody = Util_SafeRealloc(rpcBody, rpcBodySize + lastComponentSize + 1);
-         memcpy(rpcBody + rpcBodySize, lastComponentStart, lastComponentSize);
-         rpcBodySize += lastComponentSize;
-         rpcBody[rpcBodySize] = '\0';
-         rpcBodySize++;
-
-         free(currName);
-      }
-
-      if (!ghFileList || !rpcBody) {
-         Warning("DnDGtkDragDataReceivedCB: no filenames retrieved "
-                 "from URI list\n");
-         free(ghFileList);
-         free(rpcBody);
-         goto error;
-      }
-
-      /* Set the list of full paths for use in the "dnd.data.get.file" callback */
-      DnDGHFileListSet(ghFileList, ghFileListSize);
-
-      /* rpcBody (and its size) will always contain a trailing NUL character */
-      rpcBodySize--;
-   } else {
-      Warning("DnDGtkDragDataReceivedCB: unknown target format used [%s]\n",
-              dragData->data);
-      goto error;
-   }
-
-   /*
-    * Set the drag data on the host, followed by sending the drag enter
-    */
-   rpcSize = rpcHeaderSize + rpcBodySize;
-   rpc = Util_SafeMalloc(rpcSize);
-   memcpy(rpc, rpcHeader, rpcHeaderSize);
-   memcpy(rpc + rpcHeaderSize, rpcBody, rpcBodySize);
-   free(rpcBody);
-
-   Debug("DnDGtkDragMotionCB: Sending: [%s] (%"FMTSZ"u)\n",
-         CPName_Print(rpc, rpcSize), rpcSize);
-   if (!RpcOut_SendOneRaw(rpc, rpcSize, NULL, NULL)) {
-      Warning("DnDGtkDragMotionCB: failed to send dnd.data.set message\n");
-      free(rpc);
-      goto error;
-   }
-
-   free(rpc);
-
-   if (!RpcOut_sendOne(NULL, NULL, "dnd.enter 1 CF_HDROP")) {
-      Warning("DnDGtkDragMotionCB: failed to send dnd.enter message\n");
-      goto error;
-   }
-
-   return;
-
-error:
-   RpcOut_sendOne(NULL, NULL, "dnd.notpending");
-   DnDGHCancel(widget);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDGtkDragDropCB --
- *
- *    "drag_drop" signal handler for GTK.  This is invoked when a mouse button
- *    release occurs on our widget.  We generate that mouse button release in
- *    DnDRpcInFinishCB() when the host indicates that the drop has occurred and
- *    the files have been successfully transferred to the guest.
- *
- * Results:
- *    TRUE indicates to GTK that it need not run other handlers, FALSE
- *    otherwise.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static gboolean
-DnDGtkDragDropCB(GtkWidget *widget,  // IN: widget event occurred on
-                 GdkDragContext *dc, // IN: Destination drag context
-                 gint x,             // IN: x coordinate of drop
-                 gint y,             // IN: y coordinate of drop
-                 guint time,         // IN: time of event
-                 gpointer data)      // IN: our private data
-{
-   ASSERT(widget);
-   ASSERT(widget == data);
-
-   Debug("DnDGtkDragDropCB: entry (%d, %d)\n", x, y);
-
-   /* Remove timeout callback that was set in case we didn't get here */
-   if (gGHState.event) {
-      Debug("DnDGtkDragDropCB: removed pending event\n");
-      EventManager_Remove(gGHState.event);
-      gGHState.event = NULL;
-   }
-
-   /* Hide our window so we don't receive stray signals */
-   if (!gUnity) {
-      gtk_widget_hide(widget);
-   }
-
-   gtk_drag_finish(dc, TRUE, FALSE, time);
-
-   /* Reset all Guest->Host state */
-   DnDGHStateInit(widget);
-
-   return FALSE;
-}
-
-
-/*
- * Utility functions
- */
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnD_GetNewFileRoot --
- *
- *    Convenience function that gets a new file root for use on a single DnD
- *    operation and sets the global file root variable accordingly.
- *
- * Results:
- *    Size of root string (not including NUL terminator).
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-DnD_GetNewFileRoot(char *fileRoot,         // IN/OUT
-                   int bufSize)            // IN: sizeof fileRoot
-{
-   char *newDir = NULL;
-   size_t fileRootSize;
-
-   newDir = DnD_CreateStagingDirectory();
-   if (newDir == NULL) {
-      /*
-       * Fallback on base of file root if we couldn't create a staging
-       * directory for this DnD operation.  This is what Windows DnD does.
-       */
-      Str_Strcpy(fileRoot, DnD_GetFileRoot(), bufSize);
-      return strlen(fileRoot);
-   } else {
-      fileRootSize = strlen(newDir);
-      ASSERT(fileRootSize < bufSize);
-      memcpy(fileRoot, newDir, fileRootSize);
-      fileRoot[fileRootSize] = '\0';
-      free(newDir);
-      return fileRootSize;
-   }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDSendVmxNewFileRoot --
- *
- *    Sends the VMX a new file root with the provided RPC command.
- *
- * Results:
- *    TRUE on success, FALSE on failure
- *
- * Side effects:
- *    gFileRoot is repopulated.
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-DnDSendVmxNewFileRoot(char *rpcCmd)     // IN: RPC command
-{
-   int32 rpcCommandSize;
-   int32 cpNameSize;
-   int32 rpcMessageSize;
-   char *rpcMessage;
-   char *cur;
-
-   /* Repopulate gFileRoot */
-   gFileRootSize = DnD_GetNewFileRoot(gFileRoot, sizeof gFileRoot);
-
-   /*
-    * Here we must convert the file root before sending it across the
-    * backdoor.  We can only communicate with new VMXs (v2 DnD), so we only
-    * need to handle that case here.
-    *
-    * <rpcCmd> <file root in local format><NUL><file root in CPName>
-    */
-   rpcCommandSize = strlen(rpcCmd);
-
-   /*
-    * ConvertToRoot below will append the root share name, so we need to
-    * make room for it in our buffer.
-    */
-   rpcMessageSize = rpcCommandSize + 1 +
-                    gFileRootSize + 1 +
-                    HGFS_STR_LEN(HGFS_SERVER_POLICY_ROOT_SHARE_NAME) + 1 +
-                    gFileRootSize + 1;
-
-   rpcMessage = Util_SafeCalloc(1, rpcMessageSize);
-   memcpy(rpcMessage, rpcCmd, rpcCommandSize);
-   rpcMessage[rpcCommandSize] = ' ';
-   cur = rpcMessage + rpcCommandSize + 1;
-
-   memcpy(cur, gFileRoot, gFileRootSize);
-   cur += gFileRootSize;
-   *cur = '\0';
-   cur++;
-
-   Debug("DnDSendVmxNewFileRoot: calling CPNameUtil_ConvertToRoot(%s, %"FMTSZ"u, %p)\n",
-         gFileRoot, rpcMessageSize - (cur - rpcMessage), cur);
-   cpNameSize = CPNameUtil_ConvertToRoot(gFileRoot,
-                                         rpcMessageSize - (cur - rpcMessage),
-                                         cur);
-   if (cpNameSize < 0) {
-      Debug("DnDSendVmxNewFileRoot: Could not convert file root to CPName\n");
-      free(rpcMessage);
-      return FALSE;
-   }
-
-   /* Readjust message size for actual length */
-   rpcMessageSize = rpcCommandSize + 1 +
-                    gFileRootSize + 1 +
-                    cpNameSize + 1;
-
-   Debug("DnDSendVmxNewFileRoot: sending root [%s] (%d)\n",
-         CPName_Print(rpcMessage, rpcMessageSize), rpcMessageSize);
-
-   /*
-    * We must use RpcOut_SendOneRaw() here since RpcOut_sendOne() assumes a
-    * string and we are using CPName format.
-    */
-   if (!RpcOut_SendOneRaw(rpcMessage, rpcMessageSize, NULL, NULL)) {
-      Debug("DnDSendVmxNewFileRoot: Failed to send %s message to host\n", rpcCmd);
-      free(rpcMessage);
-      return FALSE;
-   }
-
-   free(rpcMessage);
-   return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDFakeXEvents --
- *
- *    Fake X mouse events and window movement for the provided Gtk widget.
- *
- *    This function will optionally show the widget, move the provided widget
- *    to either the provided location or the current mouse position if no
- *    coordinates are provided, and cause a button press or release event.
- *
- *
- * Results:
- *    TRUE on success, FALSE on failure.
- *
- * Side effects:
- *    Other X events should be generated from those faked here.
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-DnDFakeXEvents(GtkWidget *widget,  // IN: the Gtk widget
-               Bool showWidget,    // IN: whether to show Gtk widget
-               Bool buttonEvent,   // IN: whether to send a button event
-               Bool buttonPress,   // IN: whether to press or release mouse
-               Bool moveWindow,    // IN: whether to move our window too
-               Bool coordsProvided,// IN: whether coordinates provided
-               int xCoord,         // IN: x coordinate
-               int yCoord)         // IN: y coordinate
-{
-   Window rootWnd;
-   Bool ret;
-   Display *dndXDisplay;
-   Window dndXWindow;
-
-   ASSERT(widget);
-
-   dndXDisplay = GDK_WINDOW_XDISPLAY(widget->window);
-   dndXWindow = GDK_WINDOW_XWINDOW(widget->window);
-
-   /*
-    * Turn on X synchronization in order to ensure that our X events occur in
-    * the order called.  In particular, we want the window movement to occur
-    * before the mouse movement so that the events we are coercing do in fact
-    * happen.
-    */
-   XSynchronize(dndXDisplay, True);
-
-   if (showWidget) {
-      Debug("DnDFakeXEvents: showing Gtk widget\n");
-      gtk_widget_show(widget);
-      gdk_window_show(widget->window);
-   }
-
-   /* Get the current location of the mouse if coordinates weren't provided. */
-   if (!coordsProvided) {
-      Window rootReturn;
-      Window childReturn;
-      int rootXReturn;
-      int rootYReturn;
-      int winXReturn;
-      int winYReturn;
-      unsigned int maskReturn;
-
-      rootWnd = RootWindow(dndXDisplay, DefaultScreen(dndXDisplay));
-      ret = XQueryPointer(dndXDisplay, rootWnd, &rootReturn, &childReturn,
-                          &rootXReturn, &rootYReturn, &winXReturn, &winYReturn,
-                          &maskReturn);
-      if (ret == False) {
-         Warning("DnDFakeXEvents: XQueryPointer() returned False.\n");
-         XSynchronize(dndXDisplay, False);
-         return FALSE;
-      }
-
-      Debug("DnDFakeXEvents: mouse is at (%d, %d)\n", rootXReturn, rootYReturn);
-
-      xCoord = rootXReturn;
-      yCoord = rootYReturn;
-   }
-
-   if (moveWindow) {
-      /*
-       * Make sure the window is at this point and at the top (raised).  The
-       * window is resized to be a bit larger than we would like to increase
-       * the likelihood that mouse events are attributed to our window -- this
-       * is okay since the window is invisible and hidden on cancels and DnD
-       * finish.
-       */
-      XMoveResizeWindow(dndXDisplay, dndXWindow, xCoord, yCoord, 25, 25);
-      XRaiseWindow(dndXDisplay, dndXWindow);
-   }
-
-   /*
-    * Generate mouse movements over the window.  The second one makes ungrabs
-    * happen more reliably on KDE, but isn't necessary on GNOME.
-    */
-   XTestFakeMotionEvent(dndXDisplay, -1, xCoord, yCoord, CurrentTime);
-   XTestFakeMotionEvent(dndXDisplay, -1, xCoord + 1, yCoord + 1, CurrentTime);
-
-   if (buttonEvent) {
-      Debug("DnDFakeXEvents: faking left mouse button %s\n",
-            buttonPress ? "press" : "release");
-      XTestFakeButtonEvent(dndXDisplay, 1, buttonPress, CurrentTime);
-   }
-
-   XSynchronize(dndXDisplay, False);
-
-   return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDSendEscapeKey --
- *
- *    Sends the escape key, canceling any pending drag and drop on the guest.
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-DnDSendEscapeKey(GtkWidget *mainWnd)  // IN
-{
-   Display *dndXDisplay;
-   uint32 escKeycode;
-
-   Debug("DnDRpcInFinishCB: faking ESC key press/release\n");
-
-   dndXDisplay = GDK_WINDOW_XDISPLAY(mainWnd->window);
-   escKeycode = XKeysymToKeycode(dndXDisplay, XK_Escape);
-
-   XTestFakeKeyEvent(dndXDisplay, escKeycode, TRUE, CurrentTime);
-   XTestFakeKeyEvent(dndXDisplay, escKeycode, FALSE, CurrentTime);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDGHDragPending --
- *
- *    Determine whether a drag is currently pending within the guest by
- *    inspecting the internal state of the X server.  Note that Gtk supports
- *    both the Xdnd and Motif protocols, so we check each one of those.
- *
- * Results:
- *    TRUE if a Drag operation is pending (waiting for a drop), FALSE
- *    otherwise.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE Bool
-DnDGHDragPending(GtkWidget *widget) // IN: our widget
-{
-   /* Xdnd is much more prevalent, so call it first */
-   return DnDGHXdndDragPending(widget) || DnDGHMotifDragPending(widget);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDGHXdndDragPending --
- *
- *    Determines whether an Xdnd protocol drag is pending.
- *
- * Results:
- *    TRUE is a drag is pending, FALSE otherwise.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE Bool
-DnDGHXdndDragPending(GtkWidget *widget) // IN: our widget
-{
-   GdkAtom xDnDSelection;
-   Window owner;
-
-   xDnDSelection = gdk_atom_intern("XdndSelection", TRUE);
-   if (xDnDSelection == None) {
-      Warning("DnDGHXdndDragPending: could not obtain Xdnd selection atom\n");
-      return FALSE;
-   }
-
-   /*
-    * The XdndSelection atom will only have an owner if there is a drag in
-    * progress.
-    */
-   owner = XGetSelectionOwner(GDK_WINDOW_XDISPLAY(widget->window),
-                              GDKATOM_TO_ATOM(xDnDSelection));
-
-   Debug("DnDGHXdndDragPending: an Xdnd drag is %spending\n",
-         owner != None ? "" : "not ");
-
-   return owner != None;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDGHXdndClearPending --
- *
- *    Clear the ownership of the XdndSelection selection atom that we use to
- *    determine if a Xdnd drag is pending.
- *
- *    Note that this function should only be called when a DnD is not in
- *    progress.
- *
- *    Also note that this is function is only necessary to handle desktop
- *    environments that don't clear the selection owner themselves (read KDE).
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE void
-DnDGHXdndClearPending(GtkWidget *widget) // IN: program's widget
-{
-   GdkAtom xDnDSelection;
-
-   ASSERT(!gGHState.dragInProgress);
-
-   xDnDSelection = gdk_atom_intern("XdndSelection", TRUE);
-   if (xDnDSelection == None) {
-      return;
-   }
-
-   /* Clear current owner by setting owner to None */
-   XSetSelectionOwner(GDK_WINDOW_XDISPLAY(widget->window),
-                      GDKATOM_TO_ATOM(xDnDSelection), None, CurrentTime);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDMotifDragPending --
- *
- *    Determines whether a Motif protocol drag is pending.
- *
- *    XXX This has not yet been tested (looking for an app that actually uses
- *    the Motif protocol)
- *
- * Results:
- *    TRUE if a drag is pending, FALSE otherwise.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE Bool
-DnDGHMotifDragPending(GtkWidget *widget) // IN: our widget
-{
-   GdkAtom motifDragWindow;
-   Display *dndXDisplay;
-   int ret;
-   Window rootXWindow;
-   Atom type;
-   int format;
-   unsigned long nitems;
-   unsigned long bytesAfter;
-   unsigned char *prop;
-
-   motifDragWindow = gdk_atom_intern("_MOTIF_DRAG_WINDOW", TRUE);
-   if (motifDragWindow == None) {
-      Warning("DnDGHMotifDragPending: could not obtain Motif "
-              "drag window atom\n");
-      return FALSE;
-   }
-
-   dndXDisplay = GDK_WINDOW_XDISPLAY(widget->window);
-   rootXWindow = RootWindow(dndXDisplay, DefaultScreen(dndXDisplay));
-
-   /*
-    * Try and get the Motif drag window property from X's root window.  If one
-    * is provided, a DnD is pending.
-    */
-   ret = XGetWindowProperty(dndXDisplay, rootXWindow, GDKATOM_TO_ATOM(motifDragWindow),
-                            0, 1, False, XA_WINDOW,
-                            &type, &format, &nitems, &bytesAfter, &prop);
-   if (ret != Success) {
-      Warning("DnDGHMotifDragPending: XGetWindowProperty() error.\n");
-      return FALSE;
-   }
-
-   if (type == None) {
-      Debug("DnDGHXdndDragPending: a Motif drag is not pending\n");
-      return FALSE;
-   }
-
-   Debug("DnDGHXdndDragPending: a Motif drag is pending\n");
-
-   XFree(prop);
-   return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDGHFileListClear --
- *
- *    Clears existing Guest->Host file list, releasing any used resources.
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE void
-DnDGHFileListClear(void)
-{
-   Debug("DnDGHFileListClear: clearing G->H file list\n");
-   if (gGHState.dndFileList) {
-      free(gGHState.dndFileList);
-      gGHState.dndFileList = NULL;
-   }
-   gGHState.dndFileListSize = 0;
-   gGHState.dndFileListNext = NULL;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDGHFileListSet --
- *
- *    Sets the Guest->Host file list that is accessed through
- *    DnDGHFileListGetNext().
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    Clears the existing Guest->Host file list if it exists.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE void
-DnDGHFileListSet(char *fileList,      // IN: new Guest->Host file list
-                 size_t fileListSize) // IN: size of the provided list
-{
-   DnDGHFileListClear();
-   gGHState.dndFileList = fileList;
-   gGHState.dndFileListSize = fileListSize;
-   gGHState.dndFileListNext = fileList;
-
-   Debug("DnDGHFileListSet: [%s] (%"FMTSZ"u)\n",
-         CPName_Print(gGHState.dndFileList, gGHState.dndFileListSize),
-         gGHState.dndFileListSize);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDGHFileListGetNext --
- *
- *    Retrieves the next file in the Guest->Host file list.
- *
- *    Note that this function may only be called after calling
- *    DnDGHFileListSet() and before calling DnDGHFileListClear().
- *
- * Results:
- *    TRUE on success, FALSE on failure.  If TRUE is returned, fileName is
- *    given a pointer to the filename's location or NULL if there are no more
- *    files, and fileNameSize is given the length of fileName.
- *
- * Side effects:
- *    The fileListNext value of the Guest->Host global state is updated.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE Bool
-DnDGHFileListGetNext(char **fileName,       // OUT: fill with filename location
-                     size_t *fileNameSize)  // OUT: fill with filename length
-{
-   char const *end;
-   char const *next;
-   int len;
-
-   ASSERT(gGHState.dndFileList);
-   ASSERT(gGHState.dndFileListNext);
-   ASSERT(gGHState.dndFileListSize > 0);
-
-   /* Ensure end is the last NUL character */
-   end = CPNameUtil_Strrchr(gGHState.dndFileList, gGHState.dndFileListSize, '\0');
-   ASSERT(end);
-
-   /* Get the length of this filename and a pointer to the next one */
-   len = CPName_GetComponent(gGHState.dndFileListNext, end, &next);
-   if (len < 0) {
-      Warning("DnDGHFileListGetNext: error retrieving next component\n");
-      return FALSE;
-   }
-
-   /* No more entries in the list */
-   if (len == 0) {
-      Debug("DnDGHFileListGetNext: no more entries\n");
-      *fileName = NULL;
-      *fileNameSize = 0;
-      return TRUE;
-   }
-
-   Debug("DnDGHFileListGetNext: returning [%s] (%d)\n",
-         gGHState.dndFileListNext, len);
-
-   *fileName = gGHState.dndFileListNext;
-   *fileNameSize = len;
-   gGHState.dndFileListNext = (char *)next;
-   return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDGHStateInit --
- *
- *    Initializes the Guest->Host DnD state.
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE void
-DnDGHStateInit(GtkWidget *widget)  // IN
-{
-   Debug("DnDGHStateInit: initializing guest->host state\n");
-   gGHState.time = 0;
-   gGHState.dragContext = NULL;
-   gGHState.dragInProgress = FALSE;
-   gGHState.ungrabReceived = FALSE;
-   gGHState.event = NULL;
-   DnDGHXdndClearPending(widget);
-   if (!gUnity) {
-      gtk_widget_hide(widget);
-   }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDHGStateInit --
- *
- *    Initialize the Host->Guest DnD state.
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE void
-DnDHGStateInit(void)
-{
-   gHGDnDInProgress = FALSE;
-   gDoneDragging = FALSE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDGHCancel --
- *
- *    Resets state and sends a DnD cancel message to the host.
- *
- * Results:
- *    TRUE on success, FALSE on failure.
- *
- * Side effects:
- *    DnD operation is cancelled.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE Bool
-DnDGHCancel(GtkWidget *widget) // IN: program's widget
-{
-   /* Hide our widget so we don't receive stray signals */
-   if (widget && !gUnity) {
-      gtk_widget_hide(widget);
-   }
-
-   if (gGHState.dragContext) {
-      gdk_drag_status(gGHState.dragContext, 0, gGHState.time);
-   }
-
-   gGHState.dragInProgress = FALSE;
-
-   /*
-    * We don't initialize Guest->Host state here since an ungrab/grab/ungrab
-    * will cause a cancel but we want the drop of the DnD to still work.
-    */
-   return RpcOut_sendOne(NULL, NULL, "dnd.finish cancel");
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnDGHXEventTimeout --
- *
- *    Cleans up after fake X events do not cause intended events.  Hides the
- *    provided widget and resets all Guest->Host DnD state.
- *
- *    Note that this is expected to occur on ungrab if there is not a DnD
- *    pending, but may also occur at other times (sometimes we do not receive
- *    the drag drop after the mouse button release is faked on KDE).
- *
- *    This function is invoked by the event manager; it is added/removed
- *    to/from the queue in both DnDRpcInMouseUngrabCB() and DnDRpcInFinishCB(),
- *    and DnDGtkDragMotionCB() and DnDGtkDragDropCB() respectively.
- *
- * Results:
- *    TRUE always, so the event manager doesn't stop running.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-DnDGHXEventTimeout(void *clientData) // IN: our widget
-{
-   GtkWidget *widget = (GtkWidget *)clientData;
-
-   Debug("DnDGHXEventTimeout time out \n");
-
-   RpcOut_sendOne(NULL, NULL, "dnd.notpending");
-
-   if (!gGHState.dragInProgress && !gUnity) {
-      gtk_widget_hide(widget);
-   }
-
-   /* gGHState.event is cleared with the rest of Guest->Host state */
-   DnDGHStateInit(widget);
-
-   return TRUE;
-}
-
-
-/*
- * Public functions invoked by the rest of vmware-user
- */
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DnD_GetVmxDnDVersion --
- *
- *      Ask the vmx for it's dnd version.
- *
- * Results:
- *      The dnd version the vmx supports, 0 if the vmx doesn't know
- *      what we're talking about.
- *
- * Side effects:
- *      None
- *
- *-----------------------------------------------------------------------------
- */
-
-uint32
-DnD_GetVmxDnDVersion(void)
-{
-   char *reply = NULL;
-   size_t replyLen;
-   uint32 vmxVersion;
-
-   if (!RpcOut_sendOne(&reply, &replyLen, "vmx.capability.dnd_version")) {
-      Debug("DnD_GetVmxDnDVersion: could not get VMX DnD version "
-            "capability: %s\n", reply ? reply : "NULL");
-      vmxVersion = 0;
-   } else {
-      vmxVersion = atoi(reply);
-      ASSERT(vmxVersion > 1);      /* DnD versions start at 2 */
-   }
-
-   free(reply);
-   return vmxVersion;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DnD_RegisterCapability --
- *
- *      Register the "dnd" capability. Sometimes this needs to be done separately
- *      from the rest of DnD registration, so we provide it separately here.
- *
- * Results:
- *      TRUE on success
- *      FALSE on failure
- *
- * Side effects:
- *      None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-DnD_RegisterCapability(void)
-{
-   /* Tell the VMX about the DnD version we support. */
-   if (!RpcOut_sendOne(NULL, NULL, "tools.capability.dnd_version 2")) {
-      Debug("DnD_RegisterCapability: could not set guest DnD version capability\n");
-      return FALSE;
-   } else if (!DnDSendVmxNewFileRoot("dnd.ready enable")) {
-      Debug("DnD_RegisterCapability: failed to send dnd.ready message to host\n");
-      return FALSE;
-   }
-   return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DnD_Register --
- *
- *      Register the DnD capability, setup callbacks, initialize.
- *
- * Results:
- *      TRUE on success, FALSE otherwise.
- *
- * Side effects:
- *      mainWnd will be a dragSource in the guest, and dnd will work from
- *      host to guest.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-DnD_Register(GtkWidget *hgWnd, // IN: The widget to register as a drag source.
-             GtkWidget *ghWnd) // IN: The widget to register as a drag target.
-{
-   uint32 i;
-
-   gDragCtx = NULL;
-
-   ASSERT(hgWnd);
-   ASSERT(ghWnd);
-
-   if (DnD_GetVmxDnDVersion() < 2) {
-      goto error;
-   }
-
-   /*
-    * We can't pass in NULL to XTestQueryExtension(), so pass in a dummy
-    * variable to avoid segfaults.  If we have a reason to check the major and
-    * minor numbers of the running extension, that would go here.
-    */
-   if (!XTestQueryExtension(GDK_WINDOW_XDISPLAY(hgWnd->window),
-                            &i, &i, &i, &i)) {
-      goto error;
-   }
-
-   /* Host->Guest RPC callbacks */
-   RpcIn_RegisterCallback(gRpcIn, "dnd.data.set", DnDRpcInDataSetCB, hgWnd);
-   RpcIn_RegisterCallback(gRpcIn, "dnd.enter", DnDRpcInEnterCB, hgWnd);
-   RpcIn_RegisterCallback(gRpcIn, "dnd.move", DnDRpcInMoveCB, hgWnd);
-   RpcIn_RegisterCallback(gRpcIn, "dnd.drop", DnDRpcInDropCB, hgWnd);
-   RpcIn_RegisterCallback(gRpcIn, "dnd.data.finish", DnDRpcInDataFinishCB,
-                          hgWnd);
-
-   /* Guest->Host RPC callbacks */
-   RpcIn_RegisterCallback(gRpcIn, "dnd.ungrab",
-                          DnDRpcInMouseUngrabCB, ghWnd);
-   RpcIn_RegisterCallback(gRpcIn, "dnd.data.get.file",
-                          DnDRpcInGetNextFileCB, ghWnd);
-   RpcIn_RegisterCallback(gRpcIn, "dnd.finish",
-                          DnDRpcInFinishCB, ghWnd);
-
-   /*
-    * Setup mainWnd as a DND source/dest.
-    *
-    * Note that G->H drag targets should come first in this array.  Currently
-    * G->H only supports text/uri-list targets.
-    */
-   gTargetEntry[0].target = DRAG_TARGET_NAME_URI_LIST;
-   gTargetEntry[0].info = DRAG_TARGET_INFO_URI_LIST;
-   gTargetEntry[0].flags = 0;
-   gTargetEntry[1].target = DRAG_TARGET_NAME_TEXT_PLAIN;
-   gTargetEntry[1].info = DRAG_TARGET_INFO_TEXT_PLAIN;
-   gTargetEntry[1].flags = 0;
-   gTargetEntry[2].target = DRAG_TARGET_NAME_STRING;
-   gTargetEntry[2].info = DRAG_TARGET_INFO_STRING;
-   gTargetEntry[2].flags = 0;
-
-   /* Populate our GdkAtom table for our supported Guest->Host targets */
-   for (i = 0;
-        i < ARRAYSIZE(gTargetEntry) && i < ARRAYSIZE(gTargetEntryAtom);
-        i++) {
-      gTargetEntryAtom[i] = gdk_atom_intern(gTargetEntry[i].target, FALSE);
-   }
-
-   /* Drag source for Host->Guest */
-   gtk_drag_source_set(hgWnd, GDK_BUTTON1_MASK,
-                       gTargetEntry, ARRAYSIZE(gTargetEntry),
-                       GDK_ACTION_COPY | GDK_ACTION_MOVE);
-
-   gtk_signal_connect(GTK_OBJECT(hgWnd), "drag_begin",
-                      GTK_SIGNAL_FUNC(DnDGtkBeginCB), hgWnd);
-   gtk_signal_connect(GTK_OBJECT(hgWnd), "drag_end",
-                      GTK_SIGNAL_FUNC(DnDGtkEndCB), hgWnd);
-   gtk_signal_connect(GTK_OBJECT(hgWnd), "drag_data_get",
-                      GTK_SIGNAL_FUNC(DnDGtkDataRequestCB), hgWnd);
-
-
-   /*
-    * Drop target (destination) for Guest->Host
-    *
-    * We provide NR_GH_DRAG_TARGETS (rather than ARRAYSIZE(gTargetEntry)) to
-    * gtk_drag_dest_set() since we support less targets for G->H than H->G.
-    */
-   gtk_drag_dest_set(ghWnd,
-                     GTK_DEST_DEFAULT_MOTION,
-                     gTargetEntry, NR_GH_DRAG_TARGETS,
-                     GDK_ACTION_COPY | GDK_ACTION_MOVE);
-
-   gtk_signal_connect(GTK_OBJECT(ghWnd), "drag_motion",
-                      GTK_SIGNAL_FUNC(DnDGtkDragMotionCB), ghWnd);
-   gtk_signal_connect(GTK_OBJECT(ghWnd), "drag_data_received",
-                      GTK_SIGNAL_FUNC(DnDGtkDragDataReceivedCB),
-                      ghWnd);
-   gtk_signal_connect(GTK_OBJECT(ghWnd), "drag_drop",
-                      GTK_SIGNAL_FUNC(DnDGtkDragDropCB), ghWnd);
-
-   DnD_OnReset(hgWnd, ghWnd);
-
-   if (DnD_RegisterCapability()) {
-      return TRUE;
-   }
-
-   /*
-    * We get here if DnD registration fails for some reason
-    */
-error:
-   DnD_Unregister(hgWnd, ghWnd);
-   return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * DnD_Unregister --
- *
- *      Cleanup dnd related things.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      DnD is stopped, the rpc channel to the vmx is closed.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-DnD_Unregister(GtkWidget *hgWnd,        // IN: The widget for hg dnd
-               GtkWidget *ghWnd)        // IN: The widget for gh dnd
-{
-   RpcOut_sendOne(NULL, NULL, "dnd.ready disable");
-
-   DnDGHFileListClear();
-
-   /* Unregister source for Host->Guest DnD. */
-   gtk_drag_source_unset(hgWnd);
-   gtk_signal_disconnect_by_func(GTK_OBJECT(hgWnd),
-                                 GTK_SIGNAL_FUNC(DnDGtkBeginCB),
-                                 hgWnd);
-   gtk_signal_disconnect_by_func(GTK_OBJECT(hgWnd),
-                                 GTK_SIGNAL_FUNC(DnDGtkEndCB),
-                                 hgWnd);
-   gtk_signal_disconnect_by_func(GTK_OBJECT(hgWnd),
-                                 GTK_SIGNAL_FUNC(DnDGtkDataRequestCB),
-                                 hgWnd);
-
-   /* Unregister destination for Guest->Host DnD. */
-   gtk_drag_dest_unset(ghWnd);
-   gtk_signal_disconnect_by_func(GTK_OBJECT(ghWnd),
-                                 GTK_SIGNAL_FUNC(DnDGtkDragMotionCB),
-                                 ghWnd);
-   gtk_signal_disconnect_by_func(GTK_OBJECT(ghWnd),
-                                 GTK_SIGNAL_FUNC(DnDGtkDragDataReceivedCB),
-                                 ghWnd);
-   gtk_signal_disconnect_by_func(GTK_OBJECT(ghWnd),
-                                 GTK_SIGNAL_FUNC(DnDGtkDragDropCB),
-                                 ghWnd);
-
-   RpcIn_UnregisterCallback(gRpcIn, "dnd.data.set");
-   RpcIn_UnregisterCallback(gRpcIn, "dnd.enter");
-   RpcIn_UnregisterCallback(gRpcIn, "dnd.move");
-   RpcIn_UnregisterCallback(gRpcIn, "dnd.drop");
-   RpcIn_UnregisterCallback(gRpcIn, "dnd.data.finish");
-
-   /* Guest->Host RPC callbacks */
-   RpcIn_UnregisterCallback(gRpcIn, "dnd.ungrab");
-   RpcIn_UnregisterCallback(gRpcIn, "dnd.data.get.file");
-   RpcIn_UnregisterCallback(gRpcIn, "dnd.finish");
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnD_OnReset --
- *
- *    Handles reinitializing DnD state on a reset.
- *
- * Results:
- *    None.
- *
- * Side effects:
- *    DnD is stopped and restarted.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-DnD_OnReset(GtkWidget *hgWnd,   // IN: The widget for hg dnd
-            GtkWidget *ghWnd)   // IN: The widget for gh dnd
-
-{
-   Debug("DnD_OnReset: entry\n");
-
-   /* Cancel file transfer. */
-   if (gHGDnDInProgress || gHGDataPending) {
-      DnD_DeleteStagingFiles(gFileRoot, FALSE);
-      if (DnD_BlockIsReady(&gBlockCtrl) &&
-          !gBlockCtrl.RemoveBlock(gBlockCtrl.fd, gFileRoot)) {
-         Warning("DnD_OnReset: could not remove block on %s\n",
-                 gFileRoot);
-      }
-   }
-
-   /*
-    * If a DnD in either direction was in progress during suspend, send an
-    * escape to cancel the operation and reset the pointer state.
-    */
-   if (gHGDnDInProgress) {
-      Debug("DnD_OnReset: sending hgWnd escape\n");
-      DnDSendEscapeKey(hgWnd);
-   }
-
-   if (gGHState.dragInProgress) {
-      Debug("DnD_OnReset: sending ghWnd escape\n");
-      DnDSendEscapeKey(ghWnd);
-   }
-
-   if (gGHState.dragInProgress) {
-      Debug("DnD_OnReset: canceling host->guest DnD\n");
-      DnDGHCancel(ghWnd);
-   }
-
-   /* Reset DnD state. */
-   DnDHGStateInit();
-   DnDGHStateInit(ghWnd);
-   DnDGHFileListClear();
-   DnD_SetMode(FALSE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnD_InProgress --
- *
- *    Indicates whether a DnD (or its data transfer) is currently in progress.
- *
- * Results:
- *    TRUE if a DnD is in progress, FALSE otherwise.
- *
- * Side effects:
- *    None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-DnD_InProgress(void)
-{
-   return gGHState.dragInProgress || gHGDnDInProgress || gHGDataPending;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * DnD_SetMode --
- *
- *      Sets dnd mode to single window or unity mode.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      Controls if the g->h det window is automatically hidden.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-DnD_SetMode(Bool unity) // IN
-{
-   gUnity = unity;
-}
diff --git a/open-vm-tools/vmware-user/dndUI.cpp b/open-vm-tools/vmware-user/dndUI.cpp
deleted file mode 100644 (file)
index 1b96ef0..0000000
+++ /dev/null
@@ -1,2019 +0,0 @@
-/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/**
- * @file dndUI.cpp --
- *
- * This class implements stubs for the methods that allow DnD between
- * host and guest.
- */
-
-#include "dndUI.h"
-
-extern "C" {
-#include "vmwareuserInt.h"
-#include "vmblock.h"
-#include "file.h"
-#include "dnd.h"
-#include "dndMsg.h"
-#include "dndClipboard.h"
-#include "cpName.h"
-#include "debug.h"
-#include "cpNameUtil.h"
-#include "hostinfo.h"
-#include "rpcout.h"
-#include "eventManager.h"
-#include "unity.h"
-#include <gtk/gtk.h>
-#include <X11/extensions/XTest.h>       /* for XTest*() */
-#include "vmware/guestrpc/tclodefs.h"
-}
-
-#include "dndGuest.h"
-#include "copyPasteDnDWrapper.h"
-
-/**
- *
- * Constructor.
- */
-
-DnDUI::DnDUI(DblLnkLst_Links *eventQueue)
-    : m_eventQueue(eventQueue),
-      m_DnD(NULL),
-      m_detWnd(NULL),
-      m_blockCtrl(NULL),
-      m_HGGetDataInProgress(false),
-      m_blockAdded(false),
-      m_GHDnDInProgress(false),
-      m_GHDnDDataReceived(false),
-      m_unityMode(false),
-      m_inHGDrag(false),
-      m_effect(DROP_NONE),
-      m_isFileDnD(false),
-      m_mousePosX(0),
-      m_mousePosY(0),
-      m_dc(NULL),
-      m_destDropTime(0)
-{
-   Debug("%s: enter\n", __FUNCTION__);
-}
-
-
-/**
- *
- * Destructor.
- */
-
-DnDUI::~DnDUI()
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   if (m_DnD) {
-      delete m_DnD;
-   }
-   if (m_detWnd) {
-      delete m_detWnd;
-   }
-   CPClipboard_Destroy(&m_clipboard);
-}
-
-
-/**
- *
- * Initialize DnDUI object.
- */
-
-bool
-DnDUI::Init()
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   char *reply = NULL;
-   size_t replyLen;
-   bool ret = true;
-
-   ASSERT(m_eventQueue);
-   CPClipboard_Init(&m_clipboard);
-   m_DnD = new DnD(m_eventQueue);
-   if (!m_DnD) {
-      Debug("%s: unable to allocate DnD object\n", __FUNCTION__);
-      goto fail;
-   }
-   m_detWnd = new DragDetWnd();
-   if (!m_detWnd) {
-      Debug("%s: unable to allocate DragDetWnd object\n", __FUNCTION__);
-      goto fail;
-   }
-
-#if defined(DETWNDDEBUG)
-
-   /*
-    * This code can only be called when DragDetWnd is derived from
-    * Gtk::Window. The normal case is that DragDetWnd is an instance of
-    * Gtk::Invisible, which doesn't implement the methods that SetAttributes
-    * relies upon.
-    */
-
-   m_detWnd->SetAttributes();
-#endif
-
-   SetTargetsAndCallbacks();
-
-   /* Exchange dnd version information with the VMX */
-   if (!RpcOut_sendOne(NULL, NULL, "tools.capability.dnd_version 3")) {
-      Debug("%s: could not set guest dnd version capability\n", __FUNCTION__);
-      goto fail;
-   } else {
-      if (!RpcOut_sendOne(&reply, &replyLen, "vmx.capability.dnd_version")) {
-         Debug("%s: could not get VMX dnd version capability\n",
-               __FUNCTION__);
-         goto fail;
-      } else if (atoi(reply) < 3) {
-         Debug("%s: VMX DnD version is less than 3.\n", __FUNCTION__);
-         goto fail;
-      }
-   }
-
-   Debug("%s: VMX version ok: %d\n", __FUNCTION__, atoi(reply));
-
-   /* Set common layer callbacks. */
-   m_DnD->dragStartChanged.connect(
-      sigc::mem_fun(this, &DnDUI::CommonDragStartCB));
-   m_DnD->fileCopyDoneChanged.connect(
-      sigc::mem_fun(this, &DnDUI::CommonSourceFileCopyDoneCB));
-   m_DnD->updateDetWndChanged.connect(
-      sigc::mem_fun(this, &DnDUI::CommonUpdateDetWndCB));
-   m_DnD->updateUnityDetWndChanged.connect(
-      sigc::mem_fun(this, &DnDUI::CommonUpdateUnityDetWndCB));
-   m_DnD->moveDetWndToMousePos.connect(
-      sigc::mem_fun(this, &DnDUI::CommonMoveDetWndToMousePos));
-   m_DnD->sourceCancelChanged.connect(
-      sigc::mem_fun(this, &DnDUI::CommonSourceCancelCB));
-   m_DnD->targetPrivateDropChanged.connect(
-      sigc::mem_fun(this, &DnDUI::CommonDestPrivateDropCB));
-   m_DnD->ghCancel.connect(
-      sigc::mem_fun(this, &DnDUI::CommonDestCancelCB));
-   m_DnD->sourceDropChanged.connect(
-      sigc::mem_fun(this, &DnDUI::CommonSourceDropCB));
-   m_DnD->updateMouseChanged.connect(
-      sigc::mem_fun(this, &DnDUI::CommonUpdateMouseCB));
-
-   /* Set Gtk+ callbacks for source. */
-   m_detWnd->signal_drag_begin().connect(
-      sigc::mem_fun(this, &DnDUI::GtkSourceDragBeginCB));
-   m_detWnd->signal_drag_data_get().connect(
-      sigc::mem_fun(this, &DnDUI::GtkSourceDragDataGetCB));
-   m_detWnd->signal_drag_end().connect(
-      sigc::mem_fun(this, &DnDUI::GtkSourceDragEndCB));
-
-   CommonUpdateDetWndCB(false, 0, 0);
-   CommonUpdateUnityDetWndCB(false, 0, false);
-   goto out;
-fail:
-   ret = false;
-   if (m_DnD) {
-      delete m_DnD;
-      m_DnD = NULL;
-   }
-   if (m_detWnd) {
-      delete m_detWnd;
-      m_detWnd = NULL;
-   }
-out:
-   if (reply) {
-      free(reply);
-   }
-   return ret;
-}
-
-
-/**
- *
- * Setup targets we support, claim ourselves as a drag destination, and
- * register callbacks for Gtk+ drag and drop callbacks the platform will
- * send to us.
- */
-
-void
-DnDUI::SetTargetsAndCallbacks()
-{
-   Debug("%s: enter\n", __FUNCTION__);
-
-   /* Construct supported target list for HG DnD. */
-   std::list<Gtk::TargetEntry> targets;
-
-   /* File DnD. */
-   targets.push_back(Gtk::TargetEntry(DRAG_TARGET_NAME_URI_LIST));
-
-   /* RTF text DnD. */
-   targets.push_back(Gtk::TargetEntry(TARGET_NAME_APPLICATION_RTF));
-   targets.push_back(Gtk::TargetEntry(TARGET_NAME_TEXT_RICHTEXT));
-
-   /* Plain text DnD. */
-   targets.push_back(Gtk::TargetEntry(TARGET_NAME_STRING));
-   targets.push_back(Gtk::TargetEntry(TARGET_NAME_TEXT_PLAIN));
-   targets.push_back(Gtk::TargetEntry(TARGET_NAME_UTF8_STRING));
-   targets.push_back(Gtk::TargetEntry(TARGET_NAME_COMPOUND_TEXT));
-
-   /*
-    * We don't want Gtk handling any signals for us, we want to
-    * do it ourselves based on the results from the guest.
-    *
-    * Second argument in drag_dest_set defines the automatic behaviour options
-    * of the destination widget. We used to not define it (0) and in some
-    * distributions (like Ubuntu 6.10) DragMotion only get called once,
-    * and not send updated mouse position to guest, and also got cancel
-    * signal when user drop the file (bug 175754). With flag DEST_DEFAULT_MOTION
-    * the bug is fixed. Almost all other example codes use DEST_DEFAULT_ALL
-    * but in our case, we will call drag_get_data during DragMotion, and
-    * will cause X dead with DEST_DEFAULT_ALL. The reason is unclear.
-    */
-   m_detWnd->drag_dest_set(targets, Gtk::DEST_DEFAULT_MOTION,
-                           Gdk::ACTION_COPY | Gdk::ACTION_MOVE);
-   m_detWnd->signal_drag_leave().connect(sigc::mem_fun(this, &DnDUI::GtkDestDragLeaveCB));
-   m_detWnd->signal_drag_motion().connect(sigc::mem_fun(this, &DnDUI::GtkDestDragMotionCB));
-   m_detWnd->signal_drag_drop().connect(sigc::mem_fun(this, &DnDUI::GtkDestDragDropCB));
-   m_detWnd->signal_drag_data_received().connect(sigc::mem_fun(this, &DnDUI::GtkDestDragDataReceivedCB));
-}
-
-/* Begin of callbacks issued by common layer code */
-
-/**
- *
- * Reset Callback to reset dnd ui state.
- */
-
-void
-DnDUI::CommonResetCB(void)
-{
-   Debug("%s: entering\n", __FUNCTION__);
-   m_GHDnDDataReceived = false;
-   m_HGGetDataInProgress = false;
-   m_GHDnDInProgress = false;
-   m_effect = DROP_NONE;
-   m_inHGDrag = false;
-   m_dc = NULL;
-   m_isFileDnD = false;
-   RemoveBlock();
-}
-
-
-/**
- *
- * Cancel any DnD file transfers and reset.
- */
-
-void
-DnDUI::Cancel()
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   if (m_blockAdded) {
-      /*
-       * If we don't do this, the destination will have something to
-       * copy, and likely truncated. So remove it.
-       */
-      DnD_DeleteStagingFiles(m_HGStagingDir.c_str(), false);
-   }
-   CommonResetCB();
-}
-
-
-/* Source functions for HG DnD. */
-
-/**
- *
- * Called when host successfully detected a pending HG drag.
- *
- * param[in] clip cross-platform clipboard
- * param[in] stagingDir associated staging directory
- */
-
-void
-DnDUI::CommonDragStartCB(const CPClipboard *clip, std::string stagingDir)
-{
-   Glib::RefPtr<Gtk::TargetList> targets;
-   Gdk::DragAction actions;
-   GdkEventMotion event;
-
-   CPClipboard_Clear(&m_clipboard);
-   CPClipboard_Copy(&m_clipboard, clip);
-
-   Debug("%s: enter\n", __FUNCTION__);
-
-   /*
-    * Before the DnD, we should make sure that the mouse is released
-    * otherwise it may be another DnD, not ours. Send a release, then
-    * a press here to cover this case.
-    */
-   SendFakeXEvents(false, true, false, false, false, 0, 0);
-   SendFakeXEvents(true, true, true, false, true, 0, 0);
-
-   /*
-    * Construct the target and action list, as well as a fake motion notify
-    * event that's consistent with one that would typically start a drag.
-    */
-   targets = Gtk::TargetList::create(std::list<Gtk::TargetEntry>());
-
-   if (CPClipboard_ItemExists(&m_clipboard, CPFORMAT_FILELIST)) {
-      m_HGStagingDir = stagingDir;
-      if (!m_HGStagingDir.empty()) {
-         targets->add(Glib::ustring(DRAG_TARGET_NAME_URI_LIST));
-         /* Add private data to tag dnd as originating from this vm. */
-         char *pid;
-         Debug("%s: adding re-entrant drop target, pid %d\n", __FUNCTION__, getpid());
-         pid = Str_Asprintf(NULL, "guest-dnd-target %d", static_cast<int>(getpid()));
-         if (pid) {
-            targets->add(Glib::ustring(pid));
-            free(pid);
-         }
-      }
-   }
-
-   if (CPClipboard_ItemExists(&m_clipboard, CPFORMAT_FILECONTENTS)) {
-      if (WriteFileContentsToStagingDir()) {
-         targets->add(Glib::ustring(DRAG_TARGET_NAME_URI_LIST));
-      }
-   }
-
-   if (CPClipboard_ItemExists(&m_clipboard, CPFORMAT_TEXT)) {
-      targets->add(Glib::ustring(TARGET_NAME_STRING));
-      targets->add(Glib::ustring(TARGET_NAME_TEXT_PLAIN));
-      targets->add(Glib::ustring(TARGET_NAME_UTF8_STRING));
-      targets->add(Glib::ustring(TARGET_NAME_COMPOUND_TEXT));
-   }
-
-   if (CPClipboard_ItemExists(&m_clipboard, CPFORMAT_RTF)) {
-      targets->add(Glib::ustring(TARGET_NAME_APPLICATION_RTF));
-      targets->add(Glib::ustring(TARGET_NAME_TEXT_RICHTEXT));
-   }
-
-   actions = Gdk::ACTION_COPY | Gdk::ACTION_MOVE;
-
-   /* TODO set the x/y coords to the actual drag initialization point. */
-   event.type = GDK_MOTION_NOTIFY;
-   event.window = m_detWnd->get_window()->gobj();
-   event.send_event = false;
-   event.time = GDK_CURRENT_TIME;
-   event.x = 10;
-   event.y = 10;
-   event.axes = NULL;
-   event.state = GDK_BUTTON1_MASK;
-   event.is_hint = 0;
-   event.device = gdk_device_get_core_pointer();
-   event.x_root = 0;
-   event.y_root = 5;
-
-   /* Tell Gtk that a drag should be started from this widget. */
-   m_detWnd->drag_begin(targets, actions, 1, (GdkEvent *)&event);
-   m_blockAdded = false;
-   m_isFileDnD = false;
-   SourceDragStartDone();
-   /* Initialize host hide feedback to DROP_NONE. */
-   m_effect = DROP_NONE;
-   SourceUpdateFeedback(m_effect);
-}
-
-
-/**
- *
- * Cancel current HG DnD.
- */
-
-void
-DnDUI::CommonSourceCancelCB(void)
-{
-   Debug("%s: entering\n", __FUNCTION__);
-
-   /*
-    * Force the window to show, position the mouse over it, and release.
-    * Seems like moving the window to 0, 0 eliminates frequently observed
-    * flybacks when we cancel as user moves mouse in and out of destination
-    * window in a H->G DnD.
-    */
-   CommonUpdateDetWndCB(true, 0, 0);
-   SendFakeXEvents(true, true, false, true, true, 0, 0);
-   CommonUpdateDetWndCB(false, 0, 0);
-   m_inHGDrag = false;
-   m_HGGetDataInProgress = false;
-   m_effect = DROP_NONE;
-   RemoveBlock();
-}
-
-
-/**
- *
- * Handle common layer private drop CB.
- *
- * @param[in] x position to release the mouse button (ignored).
- * @param[in] y position to release the mouse button (ignored).
- *
- * @note We ignore the coordinates, because we just need to release the mouse
- * in its current position.
- */
-
-void
-DnDUI::CommonDestPrivateDropCB(int32 x,
-                               int32 y)
-{
-   Debug("%s: entering\n", __FUNCTION__);
-   /* Unity manager in host side may already send the drop into guest. */
-   if (m_GHDnDInProgress) {
-
-      /*
-       * Release the mouse button.
-       */
-      SendFakeXEvents(false, true, false, false, false, 0, 0);
-   }
-   CommonResetCB();
-}
-
-
-/**
- *
- * Cancel current DnD (G->H only).
- */
-
-void
-DnDUI::CommonDestCancelCB(void)
-{
-   Debug("%s: entering\n", __FUNCTION__);
-   /* Unity manager in host side may already send the drop into guest. */
-   if (m_GHDnDInProgress) {
-      CommonUpdateDetWndCB(true, 0, 0);
-
-      /*
-       * Show the window, move it to the mouse position, and release the
-       * mouse button.
-       */
-      SendFakeXEvents(true, true, false, true, false, 0, 0);
-   }
-   m_destDropTime = GetTimeInMillis();
-   CommonResetCB();
-}
-
-
-/**
- *
- * Got drop from host side. Release the mouse button in the detection window
- */
-
-void
-DnDUI::CommonSourceDropCB(void)
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   CommonUpdateDetWndCB(true, 0, 0);
-
-   /*
-    * Move the mouse to the saved coordinates, and release the mouse button.
-    */
-   SendFakeXEvents(false, true, false, false, true, m_mousePosX, m_mousePosY);
-   CommonUpdateDetWndCB(false, 0, 0);
-}
-
-
-/**
- *
- * Callback when file transfer is done, which finishes the file
- * copying from host to guest staging directory.
- *
- * @param[in] success if true, transfer was successful
- * @param[in] path of staging dir (which will have a block that needs removing)
- */
-
-void
-DnDUI::CommonSourceFileCopyDoneCB(bool success,
-                                  std::vector<uint8> stagingDir)
-{
-   Debug("%s: %s\n", __FUNCTION__, success ? "success" : "failed");
-   /* Copied files are already removed in common layer. */
-   stagingDir.clear();
-   CommonResetCB();
-   m_HGGetDataInProgress = false;
-}
-
-
-/**
- *
- * Shows/hides drag detection windows based on the mask.
- *
- * @param[in] bShow if true, show the window, else hide it.
- * @param[in] x x-coordinate to which the detection window needs to be moved
- * @param[in] y y-coordinate to which the detection window needs to be moved
- */
-
-void
-DnDUI::CommonUpdateDetWndCB(bool bShow,
-                            int32 x,
-                            int32 y)
-{
-   Debug("%s: enter 0x%lx show %d x %d y %d\n",
-         __FUNCTION__,
-         (unsigned long) m_detWnd->get_window()->gobj(), bShow, x, y);
-
-   /* If the window is being shown, move it to the right place. */
-   if (bShow) {
-      x = MAX(x - DRAG_DET_WINDOW_WIDTH / 2, 0);
-      y = MAX(y - DRAG_DET_WINDOW_WIDTH / 2, 0);
-
-      m_detWnd->Show();
-      m_detWnd->Raise();
-      m_detWnd->SetGeometry(x, y, DRAG_DET_WINDOW_WIDTH * 2, DRAG_DET_WINDOW_WIDTH * 2);
-      Debug("%s: show at (%d, %d, %d, %d)\n", __FUNCTION__, x, y, DRAG_DET_WINDOW_WIDTH * 2, DRAG_DET_WINDOW_WIDTH * 2);
-      /*
-       * Wiggle the mouse here. Especially for G->H DnD, this improves
-       * reliability of making the drag escape the guest window immensly.
-       * Stolen from the legacy V2 DnD code.
-       */
-
-      SendFakeMouseMove(x, y);
-      m_detWnd->SetIsVisible(true);
-   } else {
-      Debug("%s: hide\n", __FUNCTION__);
-      m_detWnd->Hide();
-      m_detWnd->SetIsVisible(false);
-   }
-}
-
-
-/**
- *
- * Shows/hides full-screen Unity drag detection window.
- *
- * @param[in] bShow if true, show the window, else hide it.
- * @param[in] unityWndId active front window
- * @param[in] bottom if true, adjust the z-order to be bottom most.
- */
-
-void
-DnDUI::CommonUpdateUnityDetWndCB(bool bShow,
-                                 uint32 unityWndId,
-                                 bool bottom)
-{
-   Debug("%s: enter 0x%lx unityID 0x%x\n",
-         __FUNCTION__,
-         (unsigned long) m_detWnd->get_window()->gobj(),
-         unityWndId);
-   if (bShow && ((unityWndId > 0) || bottom)) {
-      int width = m_detWnd->GetScreenWidth();
-      int height = m_detWnd->GetScreenHeight();
-      m_detWnd->SetGeometry(0, 0, width, height);
-      m_detWnd->Show();
-      if (bottom) {
-         m_detWnd->Lower();
-      }
-
-      Debug("%s: show, (0, 0, %d, %d)\n", __FUNCTION__, width, height);
-   } else {
-      if (m_detWnd->GetIsVisible() == true) {
-         if (m_unityMode) {
-
-            /*
-             * Show and move detection window to current mouse position
-             * and resize.
-             */
-            SendFakeXEvents(true, false, true, true, false, 0, 0);
-         }
-      } else {
-         m_detWnd->Hide();
-         Debug("%s: hide\n", __FUNCTION__);
-      }
-   }
-}
-
-
-/**
- *
- * Move detection windows to current cursor position.
- */
-
-void
-DnDUI::CommonMoveDetWndToMousePos(void)
-{
-   SendFakeXEvents(true, false, true, true, false, 0, 0);
-}
-
-
-/**
- *
- * Handle request from common layer to update mouse position.
- *
- * @param[in] x x coordinate of pointer
- * @param[in] y y coordinate of pointer
- */
-
-void
-DnDUI::CommonUpdateMouseCB(int32 x,
-                           int32 y)
-{
-   // Position the pointer, and record its position.
-
-   SendFakeXEvents(false, false, false, false, true, x, y);
-   m_mousePosX = x;
-   m_mousePosY = y;
-
-   if (m_dc && !m_GHDnDInProgress) {
-
-      // If we are the context of a DnD, send DnD feedback to the source.
-
-      DND_DROPEFFECT effect;
-      effect = ToDropEffect((Gdk::DragAction)(m_dc->action));
-      if (effect != m_effect) {
-         m_effect = effect;
-         Debug("%s: Updating feedback\n", __FUNCTION__);
-         SourceUpdateFeedback(m_effect);
-      }
-   }
-}
-
-/* Beginning of Gtk+ Callbacks */
-
-/*
- * Source callbacks from Gtk+. Most are seen only when we are acting as a
- * drag source.
- */
-
-/**
- *
- * "drag_motion" signal handler for GTK. We should respond by setting drag
- * status. Note that there is no drag enter signal. We need to figure out
- * if a new drag is happening on our own. Also, we don't respond with a
- * "allowed" drag status right away, we start a new drag operation over VMDB
- * (which tries to notify the host of the new operation). Once the host has
- * responded), we respond with a proper drag status.
- *
- * @param[in] dc associated drag context
- * @param[in] x x coordinate of the drag motion
- * @param[in] y y coordinate of the drag motion
- * @param[in] time time of the drag motion
- *
- * @return returning false means we won't get notified of future motion. So,
- * we only return false if we don't recognize the types being offered. We
- * return true otherwise, even if we don't accept the drag right now for some
- * other reason.
- *
- * @note you may see this callback during DnD when detection window is acting
- * as a source. In that case it will be ignored. In a future refactoring,
- * we will try and avoid this.
- */
-
-bool
-DnDUI::GtkDestDragMotionCB(const Glib::RefPtr<Gdk::DragContext> &dc,
-                           int x,
-                           int y,
-                           guint timeValue)
-{
-   /*
-    * If this is a Host to Guest drag, we are done here, so return.
-    */
-   unsigned long curTime = GetTimeInMillis();
-   Debug("%s: enter dc %p, m_dc %p\n", __FUNCTION__,
-         dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL);
-   if (curTime - m_destDropTime <= 1000) {
-      Debug("%s: ignored %ld %ld %ld\n", __FUNCTION__,
-            curTime, m_destDropTime, curTime - m_destDropTime);
-      return true;
-   }
-
-   Debug("%s: not ignored %ld %ld %ld\n", __FUNCTION__,
-         curTime, m_destDropTime, curTime - m_destDropTime);
-
-   if (m_inHGDrag || m_HGGetDataInProgress) {
-      Debug("%s: ignored not in hg drag or not getting hg data\n", __FUNCTION__);
-      return true;
-   }
-
-   Gdk::DragAction srcActions;
-   Gdk::DragAction suggestedAction;
-   Gdk::DragAction dndAction = (Gdk::DragAction)0;
-   Glib::ustring target = m_detWnd->drag_dest_find_target(dc);
-
-   if (!m_DnD->IsDnDAllowed()) {
-      Debug("%s: No dnd allowed!\n", __FUNCTION__);
-      dc->drag_status(dndAction, timeValue);
-      return true;
-   }
-
-   /* Check if dnd began from this vm. */
-
-   /*
-    * TODO: Once we upgrade to shipping gtkmm 2.12, we can go back to
-    *       Gdk::DragContext::get_targets, but API/ABI broke between 2.10 and
-    *       2.12, so we work around it like this for now.
-    */
-   Glib::ListHandle<std::string, Gdk::AtomStringTraits> targets(
-      dc->gobj()->targets, Glib::OWNERSHIP_NONE);
-
-   std::list<Glib::ustring> as = targets;
-   std::list<Glib::ustring>::iterator result;
-   char *pid;
-   pid = Str_Asprintf(NULL, "guest-dnd-target %d", static_cast<int>(getpid()));
-   if (pid) {
-      result = std::find(as.begin(), as.end(), std::string(pid));
-      free(pid);
-   } else {
-      result = as.end();
-   }
-   if (result != as.end()) {
-      Debug("%s: found re-entrant drop target, pid %s\n", __FUNCTION__, pid );
-      return true;
-   }
-
-   m_dc = dc->gobj();
-
-   if (target != "") {
-      /*
-       * We give preference to the suggested action from the source, and prefer
-       * copy over move.
-       */
-      suggestedAction = dc->get_suggested_action();
-      srcActions = dc->get_actions();
-      if (suggestedAction == Gdk::ACTION_COPY || suggestedAction == Gdk::ACTION_MOVE) {
-         dndAction = suggestedAction;
-      } else if (srcActions & Gdk::ACTION_COPY) {
-         dndAction= Gdk::ACTION_COPY;
-      } else if (srcActions & Gdk::ACTION_MOVE) {
-         dndAction = Gdk::ACTION_MOVE;
-      } else {
-         dndAction = (Gdk::DragAction)0;
-      }
-   } else {
-      dndAction = (Gdk::DragAction)0;
-   }
-
-   if (dndAction != (Gdk::DragAction)0) {
-      dc->drag_status(dndAction, timeValue);
-      if (!m_GHDnDInProgress) {
-         Debug("%s: new drag, need to get data for host\n", __FUNCTION__);
-         /*
-          * This is a new drag operation. We need to start a drag thru the
-          * backdoor, and to the host. Before we can tell the host, we have to
-          * retrieve the drop data.
-          */
-         m_GHDnDInProgress = true;
-         /* only begin drag enter after we get the data */
-         /* Need to grab all of the data. */
-         m_detWnd->drag_get_data(dc, target, timeValue);
-      } else {
-         Debug("%s: Multiple drag motions before gh data has been received.\n",
-               __FUNCTION__);
-      }
-   } else {
-      Debug("%s: Invalid drag\n", __FUNCTION__);
-      return false;
-   }
-   return true;
-}
-
-
-/**
- *
- * "drag_leave" signal handler for GTK. Log the reception of this signal,
- * but otherwise unhandled in our implementation.
- *
- *  @param[in] dc drag context
- *  @param[in] time time of the drag
- */
-
-void
-DnDUI::GtkDestDragLeaveCB(const Glib::RefPtr<Gdk::DragContext> &dc,
-                          guint time)
-{
-   Debug("%s: enter dc %p, m_dc %p\n", __FUNCTION__,
-         dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL);
-
-   /*
-    * If we reach here after reset DnD, or we are getting a late
-    * DnD drag leave signal (we have started another DnD), then
-    * finish the old DnD. Otherwise, Gtk will not reset and a new
-    * DnD will not start until Gtk+ times out (which appears to
-    * be 5 minutes).
-    * See http://bugzilla.eng.vmware.com/show_bug.cgi?id=528320
-    */
-   if (!m_dc || dc->gobj() != m_dc) {
-      Debug("%s: calling drag_finish\n", __FUNCTION__);
-      dc->drag_finish(true, false, time);
-   }
-}
-
-
-/*
- * Gtk+ callbacks that are seen when we are a drag source.
- */
-
-/**
- *
- * "drag_begin" signal handler for GTK.
- *
- * @param[in] context drag context
- */
-
-void
-DnDUI::GtkSourceDragBeginCB(const Glib::RefPtr<Gdk::DragContext>& context)
-{
-   Debug("%s: enter dc %p, m_dc %p\n", __FUNCTION__,
-         context ? context->gobj() : NULL, m_dc ? m_dc : NULL);
-   m_dc = context->gobj();
-}
-
-
-/**
- *
- * "drag_data_get" handler for GTK. We don't send drop until we are done.
- *
- * @param[in] dc drag state
- * @param[in] selection_data buffer for data
- * @param[in] info unused
- * @param[in] time timestamp
- *
- * @note if the drop has occurred, the files are copied from the guest.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-DnDUI::GtkSourceDragDataGetCB(const Glib::RefPtr<Gdk::DragContext> &dc,
-                              Gtk::SelectionData& selection_data,
-                              guint info,
-                              guint time)
-{
-   size_t index = 0;
-   std::string str;
-   std::string uriList;
-   std::string stagingDirName;
-   void *buf;
-   size_t sz;
-   utf::utf8string hgData;
-   DnDFileList fList;
-   std::string pre;
-   std::string post;
-
-   const utf::string target = selection_data.get_target().c_str();
-
-   selection_data.set(target.c_str(), "");
-
-   Debug("%s: enter dc %p, m_dc %p with target %s\n", __FUNCTION__,
-         dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL,
-         target.c_str());
-
-   if (!m_inHGDrag) {
-      Debug("%s: not in drag, return\n", __FUNCTION__);
-      return;
-   }
-
-   if (target == DRAG_TARGET_NAME_URI_LIST &&
-       CPClipboard_GetItem(&m_clipboard, CPFORMAT_FILELIST, &buf, &sz)) {
-
-      /* Provide path within vmblock file system instead of actual path. */
-      stagingDirName = GetLastDirName(m_HGStagingDir);
-      if (stagingDirName.length() == 0) {
-         Debug("%s: Cannot get staging directory name, stagingDir: %s\n",
-               __FUNCTION__, m_HGStagingDir.c_str());
-         return;
-      }
-
-      if (!fList.FromCPClipboard(buf, sz)) {
-         Debug("%s: Can't get data from clipboard\n", __FUNCTION__);
-         return;
-      }
-
-      /* Provide URIs for each path in the guest's file list. */
-      if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) {
-         pre = FCP_GNOME_LIST_PRE;
-         post = FCP_GNOME_LIST_POST;
-      } else if (FCP_TARGET_INFO_URI_LIST == info) {
-         pre = DND_URI_LIST_PRE_KDE;
-         post = DND_URI_LIST_POST;
-      } else {
-         Debug("%s: Unknown request target: %s\n", __FUNCTION__,
-               selection_data.get_target().c_str());
-         return;
-      }
-
-      /* Provide path within vmblock file system instead of actual path. */
-      hgData = fList.GetRelPathsStr();
-
-      /* Provide URIs for each path in the guest's file list. */
-      while ((str = GetNextPath(hgData, index).c_str()).length() != 0) {
-         uriList += pre;
-         if (DnD_BlockIsReady(m_blockCtrl)) {
-            uriList += m_blockCtrl->blockRoot;
-            uriList += DIRSEPS + stagingDirName + DIRSEPS + str + post;
-         } else {
-            uriList += DIRSEPS + m_HGStagingDir + DIRSEPS + str + post;
-         }
-      }
-
-      /*
-       * This seems to be the best place to do the blocking. If we do
-       * it in the source drop callback from the DnD layer, we often
-       * find ourselves adding the block too late; the user will (in
-       * GNOME, in the dest) be told that it could not find the file,
-       * and if you click retry, it is there, meaning the block was
-       * added too late).
-       *
-       * We find ourselves in this callback twice for each H->G DnD.
-       * We *must* always set the selection data, when called, or else
-       * the DnD for that context will fail, but we *must not* add the
-       * block twice or else things get confused. So we add a check to
-       * see if we are in the right state (no block yet added, and we
-       * are in a HG drag still, both must be true) when adding the block.
-       * Doing both of these addresses bug
-       * http://bugzilla.eng.vmware.com/show_bug.cgi?id=391661.
-       */
-      if (!m_blockAdded && m_inHGDrag) {
-         m_HGGetDataInProgress = true;
-         m_isFileDnD = true;
-         AddBlock();
-      } else {
-         Debug("%s: not calling AddBlock\n", __FUNCTION__);
-      }
-      selection_data.set(DRAG_TARGET_NAME_URI_LIST, uriList.c_str());
-      Debug("%s: exit\n", __FUNCTION__);
-      return;
-   }
-
-   if (target == DRAG_TARGET_NAME_URI_LIST &&
-       CPClipboard_ItemExists(&m_clipboard, CPFORMAT_FILECONTENTS)) {
-      Debug("%s: Providing uriList [%s] for file contents DnD\n",
-            __FUNCTION__, m_HGFileContentsUriList.c_str());
-
-      selection_data.set(DRAG_TARGET_NAME_URI_LIST,
-                         m_HGFileContentsUriList.c_str());
-      return;
-   }
-
-   if ((target == TARGET_NAME_STRING ||
-        target == TARGET_NAME_TEXT_PLAIN ||
-        target == TARGET_NAME_UTF8_STRING ||
-        target == TARGET_NAME_COMPOUND_TEXT) &&
-       CPClipboard_GetItem(&m_clipboard, CPFORMAT_TEXT, &buf, &sz)) {
-      Debug("%s: providing plain text, size %"FMTSZ"u\n", __FUNCTION__, sz);
-      selection_data.set(target.c_str(), (const char *)buf);
-      return;
-   }
-
-   if ((target == TARGET_NAME_APPLICATION_RTF ||
-        target == TARGET_NAME_TEXT_RICHTEXT) &&
-       CPClipboard_GetItem(&m_clipboard, CPFORMAT_RTF, &buf, &sz)) {
-      Debug("%s: providing rtf text, size %"FMTSZ"u\n", __FUNCTION__, sz);
-      selection_data.set(target.c_str(), (const char *)buf);
-      return;
-   }
-
-   /* Can not get any valid data, cancel this HG DnD. */
-   Debug("%s: no valid data for HG DnD\n", __FUNCTION__);
-   m_DnD->SourceCancel();
-   CommonResetCB();
-}
-
-
-/**
- *
- * "drag_end" handler for GTK. Received by drag source.
- *
- * @param[in] dc drag state
- */
-
-void
-DnDUI::GtkSourceDragEndCB(const Glib::RefPtr<Gdk::DragContext> &dc)
-{
-   Debug("%s: entering dc %p, m_dc %p\n", __FUNCTION__,
-         dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL);
-
-   /*
-    * We may see a drag end for the previous DnD, but after a new
-    * DnD has started. If so, ignore it.
-    */
-   if (m_dc && dc && (m_dc != dc->gobj())) {
-      Debug("%s: got old dc (new DnD started), ignoring\n", __FUNCTION__);
-      return;
-   }
-
-   /*
-    * If we are a file DnD, don't call CommonResetCB() here, since
-    * we will do so in the fileCopyDoneChanged callback.
-    */
-   if (!m_isFileDnD) {
-      CommonResetCB();
-   }
-   m_inHGDrag = false;
-}
-
-/* Gtk+ callbacks seen when we are a drag destination. */
-
-/**
- *
- * "drag_data_received" signal handler for GTK. We requested the drag
- * data earlier from some drag source on the guest; this is the response.
- *
- * This is for G->H DnD.
- *
- * @param[in] dc drag context
- * @param[in] x where the drop happened
- * @param[in] y where the drop happened
- * @param[in] sd the received data
- * @param[in] info the info that has been registered with the target in the
- * target list.
- * @param[in] time the timestamp at which the data was received.
- */
-
-void
-DnDUI::GtkDestDragDataReceivedCB(const Glib::RefPtr<Gdk::DragContext> &dc,
-                                 int x,
-                                 int y,
-                                 const Gtk::SelectionData& sd,
-                                 guint info,
-                                 guint time)
-{
-   Debug("%s: enter dc %p, m_dc %p\n", __FUNCTION__,
-         dc ? dc->gobj() : NULL, m_dc ? m_dc : NULL);
-   /* The GH DnD may already finish before we got response. */
-   if (!m_GHDnDInProgress) {
-      Debug("%s: not valid\n", __FUNCTION__);
-      return;
-   }
-
-   CPClipboard_Clear(&m_clipboard);
-
-   /*
-    * Try to get data provided from the source.  If we cannot get any data,
-    * there is no need to inform the guest of anything. If there is no data,
-    * reset, so that the next drag_motion callback that we see will be allowed
-    * to request data again.
-    */
-   if (SetCPClipboardFromGtk(sd) == false) {
-      Debug("%s: Failed to set CP clipboard.\n", __FUNCTION__);
-      CommonResetCB();
-      return;
-   }
-   if (CPClipboard_IsEmpty(&m_clipboard)) {
-      Debug("%s: Failed getting item.\n", __FUNCTION__);
-      CommonResetCB();
-      return;
-   }
-
-   /*
-    * There are two points in the DnD process at which this is called, and both
-    * are in response to us calling drag_data_get().  The first occurs on the
-    * first "drag_motion" received and is used to start a drag; at that point
-    * we need to provide the file list to the guest so we request the data from
-    * the target.  The second occurs when the "drag_drop" signal is received
-    * and we confirm this data with the target before starting the drop.
-    *
-    * Note that we prevent against sending multiple "dragStart"s or "drop"s for
-    * each DnD.
-    */
-   if (!m_GHDnDDataReceived) {
-      Debug("%s: Drag entering.\n", __FUNCTION__);
-      m_GHDnDDataReceived = true;
-      TargetDragEnter();
-   } else {
-      Debug("%s: not !m_GHDnDDataReceived\n", __FUNCTION__);
-   }
-}
-
-
-/**
- *
- * "drag_drop" signal handler for GTK. Send the drop to the host (by
- * way of the backdoor), then tell the host to get the files.
- *
- * @param[in] dc drag context
- * @param[in] x x location of the drop
- * @param[in] y y location of the drop
- * @param[in] time timestamp for the drop
- *
- * @return true on success, false otherwise.
- */
-
-bool
-DnDUI::GtkDestDragDropCB(const Glib::RefPtr<Gdk::DragContext> &dc,
-                         int x,
-                         int y,
-                         guint time)
-{
-   Debug("%s: enter dc %p, m_dc %p x %d y %d\n", __FUNCTION__,
-         (dc ? dc->gobj() : NULL), (m_dc ? m_dc : NULL), x, y);
-
-   Glib::ustring target;
-
-   target = m_detWnd->drag_dest_find_target(dc);
-   Debug("%s: calling drag_finish\n", __FUNCTION__);
-   dc->drag_finish(true, false, time);
-
-   if (target == "") {
-      Debug("%s: No valid data on clipboard.\n", __FUNCTION__);
-      return false;
-   }
-
-   if (CPClipboard_IsEmpty(&m_clipboard)) {
-      Debug("%s: No valid data on m_clipboard.\n", __FUNCTION__);
-      return false;
-   }
-
-   return true;
-}
-
-/* General utility functions */
-
-/**
- *
- * Try to construct cross-platform clipboard data from selection data
- * provided to us by Gtk+.
- *
- * @param[in] sd Gtk selection data to convert to CP clipboard data
- *
- * @return false on failure, true on success
- */
-
-bool
-DnDUI::SetCPClipboardFromGtk(const Gtk::SelectionData& sd) // IN
-{
-   char *newPath;
-   char *newRelPath;
-   size_t newPathLen;
-   size_t index = 0;
-   DnDFileList fileList;
-   DynBuf buf;
-   uint64 totalSize = 0;
-   int64 size;
-
-   const utf::string target = sd.get_target().c_str();
-
-   /* Try to get file list. */
-   if (target == DRAG_TARGET_NAME_URI_LIST) {
-      /*
-       * Turn the uri list into two \0  delimited lists. One for full paths and
-       * one for just the last path component.
-       */
-      utf::string source = sd.get_data_as_string().c_str();
-      Debug("%s: Got file list: [%s]\n", __FUNCTION__, source.c_str());
-
-      if (sd.get_data_as_string().length() == 0) {
-         Debug("%s: empty file list!\n", __FUNCTION__);
-         return false;
-      }
-
-      /*
-       * In gnome, before file list there may be a extra line indicating it
-       * is a copy or cut.
-       */
-      if (source.length() >= 5 && source.compare(0, 5, "copy\n") == 0) {
-         source = source.erase(0, 5);
-      }
-
-      if (source.length() >= 4 && source.compare(0, 4, "cut\n") == 0) {
-         source = source.erase(0, 4);
-      }
-
-      while (source.length() > 0 &&
-             (source[0] == '\n' || source[0] == '\r' || source[0] == ' ')) {
-         source = source.erase(0, 1);
-      }
-
-      while ((newPath = DnD_UriListGetNextFile(source.c_str(),
-                                               &index,
-                                               &newPathLen)) != NULL) {
-
-         /*
-          * Parse relative path.
-          */
-         newRelPath = Str_Strrchr(newPath, DIRSEPC) + 1; // Point to char after '/'
-
-         if ((size = File_GetSize(newPath)) >= 0) {
-            totalSize += size;
-         } else {
-            Debug("%s: unable to get file size for %s\n", __FUNCTION__, newPath);
-         }
-         Debug("%s: Adding newPath '%s' newRelPath '%s'\n", __FUNCTION__,
-               newPath, newRelPath);
-         fileList.AddFile(newPath, newRelPath);
-         free(newPath);
-      }
-
-      DynBuf_Init(&buf);
-      fileList.SetFileSize(totalSize);
-      if (fileList.ToCPClipboard(&buf, false)) {
-          CPClipboard_SetItem(&m_clipboard, CPFORMAT_FILELIST, DynBuf_Get(&buf),
-                              DynBuf_GetSize(&buf));
-      }
-      DynBuf_Destroy(&buf);
-      return true;
-   }
-
-   /* Try to get plain text. */
-   if (target == TARGET_NAME_STRING ||
-       target == TARGET_NAME_TEXT_PLAIN ||
-       target == TARGET_NAME_UTF8_STRING ||
-       target == TARGET_NAME_COMPOUND_TEXT) {
-      utf::string source = sd.get_data_as_string().c_str();
-      if (source.bytes() > 0 &&
-          source.bytes() < DNDMSG_MAX_ARGSZ &&
-          CPClipboard_SetItem(&m_clipboard, CPFORMAT_TEXT, source.c_str(),
-                              source.bytes() + 1)) {
-         Debug("%s: Got text, size %"FMTSZ"u\n", __FUNCTION__, source.bytes());
-      } else {
-         Debug("%s: Failed to get text\n", __FUNCTION__);
-         return false;
-      }
-      return true;
-   }
-
-   /* Try to get RTF string. */
-   if (target == TARGET_NAME_APPLICATION_RTF ||
-       target == TARGET_NAME_TEXT_RICHTEXT) {
-      utf::string source = sd.get_data_as_string().c_str();
-      if (source.bytes() > 0 &&
-          source.bytes() < DNDMSG_MAX_ARGSZ &&
-          CPClipboard_SetItem(&m_clipboard, CPFORMAT_RTF, source.c_str(),
-                              source.bytes() + 1)) {
-         Debug("%s: Got RTF, size %"FMTSZ"u\n", __FUNCTION__, source.bytes());
-         return true;
-      } else {
-         Debug("%s: Failed to get text\n", __FUNCTION__ );
-         return false;
-      }
-   }
-   return true;
-}
-
-
-/**
- *
- * Try to get last directory name from a full path name.
- *
- * @param[in] str pathname to process
- *
- * @return last dir name in the full path name if sucess, empty str otherwise
- */
-
-std::string
-DnDUI::GetLastDirName(const std::string &str)
-{
-   std::string ret;
-   size_t start;
-   size_t end;
-
-   end = str.size() - 1;
-   if (end >= 0 && DIRSEPC == str[end]) {
-      end--;
-   }
-
-   if (end <= 0 || str[0] != DIRSEPC) {
-      return "";
-   }
-
-   start = end;
-
-   while (str[start] != DIRSEPC) {
-      start--;
-   }
-
-   return str.substr(start + 1, end - start);
-}
-
-
-/**
- *
- * Provide a substring containing the next path from the provided
- * NUL-delimited string starting at the provided index.
- *
- * @param[in] str NUL-delimited path list
- * @param[in] index current index into string
- *
- * @return a string with the next path or "" if there are no more paths.
- */
-
-utf::utf8string
-DnDUI::GetNextPath(utf::utf8string& str,
-                   size_t& index)
-{
-   utf::utf8string ret;
-   size_t start;
-
-   if (index >= str.length()) {
-      return "";
-   }
-
-   for (start = index; str[index] != '\0' && index < str.length(); index++) {
-      /*
-       * Escape reserved characters according to RFC 1630.  We'd use
-       * Escape_Do() if this wasn't a utf::string, but let's use the same table
-       * replacement approach.
-       */
-      static char const Dec2Hex[] = {
-         '0', '1', '2', '3', '4', '5', '6', '7',
-         '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
-      };
-
-      unsigned char ubyte = str[index];
-
-      if (ubyte == '#' ||   /* Fragment identifier delimiter */
-          ubyte == '?' ||   /* Query string delimiter */
-          ubyte == '*' ||   /* "Special significance within specific schemes" */
-          ubyte == '!' ||   /* "Special significance within specific schemes" */
-          ubyte == '%' ||   /* Escape character */
-          ubyte >= 0x80) {  /* UTF-8 encoding bytes */
-         str.replace(index, 1, "%");
-         str.insert(index + 1, 1, Dec2Hex[ubyte >> 4]);
-         str.insert(index + 2, 1, Dec2Hex[ubyte & 0xF]);
-         index += 2;
-      }
-   }
-
-   ret = str.substr(start, index - start);
-   Debug("%s: nextpath: %s", __FUNCTION__, ret.c_str());
-   index++;
-   return ret;
-}
-
-
-/**
- *
- * Issue a fake mouse move event to the detection window. Code stolen from
- * DnD V2 Linux guest implementation, where it was originally defined as a
- * macro.
- *
- * @param[in] x x-coordinate of location to move mouse to.
- * @param[in] y y-coordinate of location to move mouse to.
- *
- * @return true on success, false on failure.
- */
-
-bool
-DnDUI::SendFakeMouseMove(const int x,
-                         const int y)
-{
-   return SendFakeXEvents(false, false, false, false, true, x, y);
-}
-
-
-/**
- *
- * Fake X mouse events and window movement for the provided Gtk widget.
- *
- * This function will optionally show the widget, move the provided widget
- * to either the provided location or the current mouse position if no
- * coordinates are provided, and cause a button press or release event.
- *
- * @param[in] showWidget       whether to show Gtk widget
- * @param[in] buttonEvent      whether to send a button event
- * @param[in] buttonPress      whether to press or release mouse
- * @param[in] moveWindow:      whether to move our window too
- * @param[in] coordsProvided   whether coordinates provided
- * @param[in] xCoord           x coordinate
- * @param[in] yCoord           y coordinate
- *
- * @note todo this code should be implemented using GDK APIs.
- * @note todo this code should be moved into the detection window class
- *
- * @return true on success, false on failure.
- */
-
-bool
-DnDUI::SendFakeXEvents(const bool showWidget,
-                       const bool buttonEvent,
-                       const bool buttonPress,
-                       const bool moveWindow,
-                       const bool coordsProvided,
-                       const int xCoord,
-                       const int yCoord)
-{
-   GtkWidget *widget;
-   Window rootWnd;
-   bool ret = false;
-   Display *dndXDisplay;
-   Window dndXWindow;
-   Window rootReturn;
-   int x;
-   int y;
-   Window childReturn;
-   int rootXReturn;
-   int rootYReturn;
-   int winXReturn;
-   int winYReturn;
-   unsigned int maskReturn;
-
-   x = xCoord;
-   y = yCoord;
-
-   widget = GetDetWndAsWidget();
-
-   if (!widget) {
-      Debug("%s: unable to get widget\n", __FUNCTION__);
-      return false;
-   }
-
-   dndXDisplay = GDK_WINDOW_XDISPLAY(widget->window);
-   dndXWindow = GDK_WINDOW_XWINDOW(widget->window);
-   rootWnd = RootWindow(dndXDisplay, DefaultScreen(dndXDisplay));
-
-   /*
-    * Turn on X synchronization in order to ensure that our X events occur in
-    * the order called.  In particular, we want the window movement to occur
-    * before the mouse movement so that the events we are coercing do in fact
-    * happen.
-    */
-   XSynchronize(dndXDisplay, True);
-
-   if (showWidget) {
-      Debug("%s: showing Gtk widget\n", __FUNCTION__);
-      gtk_widget_show(widget);
-      gdk_window_show(widget->window);
-   }
-
-   /* Get the current location of the mouse if coordinates weren't provided. */
-   if (!coordsProvided) {
-      if (!XQueryPointer(dndXDisplay, rootWnd, &rootReturn, &childReturn,
-                         &rootXReturn, &rootYReturn, &winXReturn, &winYReturn,
-                         &maskReturn)) {
-         Warning("%s: XQueryPointer() returned False.\n", __FUNCTION__);
-         goto exit;
-      }
-
-      Debug("%s: current mouse is at (%d, %d)\n", __FUNCTION__,
-            rootXReturn, rootYReturn);
-
-      /*
-       * Position away from the edge of the window.
-       */
-      int width = m_detWnd->GetScreenWidth();
-      int height = m_detWnd->GetScreenHeight();
-      bool change = false;
-
-      x = rootXReturn;
-      y = rootYReturn;
-
-      /*
-       * first do left and top edges.
-       */
-
-      if (x <= 5) {
-         x = 6;
-         change = true;
-      }
-
-      if (y <= 5) {
-         y = 6;
-         change = true;
-      }
-
-      /*
-       * next, move result away from right and bottom edges.
-       */
-      if (x > width - 5) {
-         x = width - 6;
-         change = true;
-      }
-      if (y > height - 5) {
-         y = height - 6;
-         change = true;
-      }
-
-      if (change) {
-         Debug("%s: adjusting mouse position. root %d, %d, adjusted %d, %d\n",
-               __FUNCTION__, rootXReturn, rootYReturn, x, y);
-      }
-   }
-
-   if (moveWindow) {
-      /*
-       * Make sure the window is at this point and at the top (raised).  The
-       * window is resized to be a bit larger than we would like to increase
-       * the likelihood that mouse events are attributed to our window -- this
-       * is okay since the window is invisible and hidden on cancels and DnD
-       * finish.
-       */
-      XMoveResizeWindow(dndXDisplay, dndXWindow, x - 5 , y - 5, 25, 25);
-      XRaiseWindow(dndXDisplay, dndXWindow);
-      Debug("%s: move wnd to (%d, %d, %d, %d)\n", __FUNCTION__, x - 5, y - 5 , x + 25, y + 25);
-   }
-
-   /*
-    * Generate mouse movements over the window.  The second one makes ungrabs
-    * happen more reliably on KDE, but isn't necessary on GNOME.
-    */
-   XTestFakeMotionEvent(dndXDisplay, -1, x, y, CurrentTime);
-   XTestFakeMotionEvent(dndXDisplay, -1, x + 1, y + 1, CurrentTime);
-   Debug("%s: move mouse to (%d, %d) and (%d, %d)\n", __FUNCTION__, x, y, x + 1, y + 1);
-
-   if (buttonEvent) {
-      Debug("%s: faking left mouse button %s\n", __FUNCTION__,
-            buttonPress ? "press" : "release");
-      XTestFakeButtonEvent(dndXDisplay, 1, buttonPress, CurrentTime);
-      XSync(dndXDisplay, False);
-
-      if (!buttonPress) {
-         /*
-          * The button release simulation may be failed with some distributions
-          * like Ubuntu 10.4 and RHEL 6 for guest->host DnD. So first query
-          * mouse button status. If some button is still down, we will try
-          * mouse device level event simulation. For details please refer
-          * to bug 552807.
-          */
-         if (!XQueryPointer(dndXDisplay, rootWnd, &rootReturn, &childReturn,
-                            &rootXReturn, &rootYReturn, &winXReturn,
-                            &winYReturn, &maskReturn)) {
-            Warning("%s: XQueryPointer returned False.\n", __FUNCTION__);
-            goto exit;
-         }
-
-         if ((maskReturn & Button1Mask) ||
-             (maskReturn & Button2Mask) ||
-             (maskReturn & Button3Mask) ||
-             (maskReturn & Button4Mask) ||
-             (maskReturn & Button5Mask)) {
-            Debug("%s: XTestFakeButtonEvent was not working for button "
-                  "release, trying XTestFakeDeviceButtonEvent now.\n",
-                  __FUNCTION__);
-            ret = TryXTestFakeDeviceButtonEvent();
-         } else {
-            Debug("%s: XTestFakeButtonEvent was working for button release.\n",
-                  __FUNCTION__);
-            ret = true;
-         }
-      } else {
-         ret = true;
-      }
-   }
-
-exit:
-   XSynchronize(dndXDisplay, False);
-   return ret;
-}
-
-
-/**
- * Fake X mouse events in device level.
- *
- * XXX The function will only be called if XTestFakeButtonEvent does not work
- * for mouse button release. Later on we may only call this one for mouse
- * button simulation if this is more reliable.
- *
- * @return true on success, false on failure.
- */
-
-bool
-DnDUI::TryXTestFakeDeviceButtonEvent(void)
-{
-   XDeviceInfo *list = NULL;
-   XDeviceInfo *list2 = NULL;
-   XDevice *tdev = NULL;
-   XDevice *buttonDevice = NULL;
-   int numDevices = 0;
-   int i = 0;
-   int j = 0;
-   XInputClassInfo *ip = NULL;
-   GtkWidget *widget;
-   Display *dndXDisplay;
-
-   widget = GetDetWndAsWidget();
-
-   if (!widget) {
-      Debug("%s: unable to get widget\n", __FUNCTION__);
-      return false;
-   }
-
-   dndXDisplay = GDK_WINDOW_XDISPLAY(widget->window);
-
-   /* First get list of all input device. */
-   if (!(list = XListInputDevices (dndXDisplay, &numDevices))) {
-      Debug("%s: XListInputDevices failed\n", __FUNCTION__);
-      return false;
-   } else {
-      Debug("%s: XListInputDevices got %d devices\n", __FUNCTION__, numDevices);
-   }
-
-   list2 = list;
-
-   for (i = 0; i < numDevices; i++, list++) {
-      /* We only care about mouse device. */
-      if (list->use != IsXExtensionPointer) {
-         continue;
-      }
-
-      tdev = XOpenDevice(dndXDisplay, list->id);
-      if (!tdev) {
-         Debug("%s: XOpenDevice failed\n", __FUNCTION__);
-         continue;
-      }
-
-      for (ip = tdev->classes, j = 0; j < tdev->num_classes; j++, ip++) {
-         if (ip->input_class == ButtonClass) {
-            buttonDevice = tdev;
-            break;
-         }
-      }
-
-      if (buttonDevice) {
-         Debug("%s: calling XTestFakeDeviceButtonEvent for %s\n",
-               __FUNCTION__, list->name);
-         XTestFakeDeviceButtonEvent(dndXDisplay, buttonDevice, 1, False,
-                                    NULL, 0, CurrentTime);
-         buttonDevice = NULL;
-      }
-      XCloseDevice(dndXDisplay, tdev);
-   }
-   XFreeDeviceList(list2);
-   return true;
-}
-
-
-/**
- *
- * Get the GtkWidget pointer for a DragDetWnd object. The X11 Unity
- * implementation requires access to the drag detection window as
- * a GtkWindow pointer, which it uses to show and hide the detection
- * window. This function is also called by the code that issues fake
- * X events to the detection window.
- *
- * @return a pointer to the GtkWidget for the detection window, or NULL
- * on failure.
- */
-
-GtkWidget *
-DnDUI::GetDetWndAsWidget()
-{
-   GtkInvisible *window;
-   GtkWidget *widget = NULL;
-
-   if (!m_detWnd) {
-      return NULL;
-   }
-   window = m_detWnd->gobj();
-   if (window) {
-      widget = GTK_WIDGET(window);
-   }
-   return widget;
-}
-
-
-/**
- *
- * Add a block for the current H->G file transfer. Must be paired with a
- * call to RemoveBlock() on finish or cancellation.
- */
-
-void
-DnDUI::AddBlock()
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   if (m_blockAdded) {
-      Debug("%s: block already added\n", __FUNCTION__);
-      return;
-   }
-   if (DnD_BlockIsReady(m_blockCtrl) && m_blockCtrl->AddBlock(m_blockCtrl->fd, m_HGStagingDir.c_str())) {
-      m_blockAdded = true;
-      Debug("%s: add block for %s.\n", __FUNCTION__, m_HGStagingDir.c_str());
-   } else {
-      m_blockAdded = false;
-      Debug("%s: unable to add block dir %s.\n", __FUNCTION__, m_HGStagingDir.c_str());
-   }
-}
-
-
-/**
- *
- * Remove block for the current H->G file transfer. Must be paired with a
- * call to AddBlock(), but it will only attempt to remove block if one is
- * currently in effect.
- */
-
-void
-DnDUI::RemoveBlock()
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   if (m_blockAdded && !m_HGGetDataInProgress) {
-      Debug("%s: removing block for %s\n", __FUNCTION__, m_HGStagingDir.c_str());
-      m_blockCtrl->RemoveBlock(m_blockCtrl->fd, m_HGStagingDir.c_str());
-      m_blockAdded = false;
-   } else {
-      Debug("%s: not removing block m_blockAdded %d m_HGGetDataInProgress %d\n",
-            __FUNCTION__,
-            m_blockAdded,
-            m_HGGetDataInProgress);
-   }
-}
-
-
-/**
- *
- * Convert a Gdk::DragAction value to its corresponding DND_DROPEFFECT.
- *
- * @param[in] the Gdk::DragAction value to return.
- *
- * @return the corresponding DND_DROPEFFECT, with DROP_UNKNOWN returned
- * if no mapping is supported.
- *
- * @note DROP_NONE is not mapped in this function.
- */
-
-DND_DROPEFFECT
-DnDUI::ToDropEffect(Gdk::DragAction action)
-{
-   DND_DROPEFFECT effect;
-
-   switch(action) {
-   case Gdk::ACTION_COPY:
-   case Gdk::ACTION_DEFAULT:
-      effect = DROP_COPY;
-      break;
-   case Gdk::ACTION_MOVE:
-      effect = DROP_MOVE;
-      break;
-   case Gdk::ACTION_LINK:
-      effect = DROP_LINK;
-      break;
-   case Gdk::ACTION_PRIVATE:
-   case Gdk::ACTION_ASK:
-   default:
-      effect = DROP_UNKNOWN;
-      break;
-   }
-   return effect;
-}
-
-
-/**
- *
- * Try to extract file contents from m_clipboard. Write all files to a
- * temporary staging directory. Construct uri list.
- *
- * @return true if success, false otherwise.
- */
-
-bool
-DnDUI::WriteFileContentsToStagingDir(void)
-{
-   void *buf = NULL;
-   size_t sz = 0;
-   XDR xdrs;
-   CPFileContents fileContents;
-   CPFileContentsList *contentsList = NULL;
-   size_t nFiles = 0;
-   CPFileItem *fileItem = NULL;
-   Unicode tempDir = NULL;
-   size_t i = 0;
-   bool ret = false;
-
-   if (!CPClipboard_GetItem(&m_clipboard, CPFORMAT_FILECONTENTS, &buf, &sz)) {
-      return false;
-   }
-
-   /* Extract file contents from buf. */
-   xdrmem_create(&xdrs, (char *)buf, sz, XDR_DECODE);
-   memset(&fileContents, 0, sizeof fileContents);
-
-   if (!xdr_CPFileContents(&xdrs, &fileContents)) {
-      Debug("%s: xdr_CPFileContents failed.\n", __FUNCTION__);
-      xdr_destroy(&xdrs);
-      return false;
-   }
-   xdr_destroy(&xdrs);
-
-   contentsList = fileContents.CPFileContents_u.fileContentsV1;
-   if (!contentsList) {
-      Debug("%s: invalid contentsList.\n", __FUNCTION__);
-      goto exit;
-   }
-
-   nFiles = contentsList->fileItem.fileItem_len;
-   if (0 == nFiles) {
-      Debug("%s: invalid nFiles.\n", __FUNCTION__);
-      goto exit;
-   }
-
-   fileItem = contentsList->fileItem.fileItem_val;
-   if (!fileItem) {
-      Debug("%s: invalid fileItem.\n", __FUNCTION__);
-      goto exit;
-   }
-
-   /*
-    * Write files into a temporary staging directory. These files will be moved
-    * to final destination, or deleted on next reboot.
-    */
-   tempDir = DnD_CreateStagingDirectory();
-   if (!tempDir) {
-      Debug("%s: DnD_CreateStagingDirectory failed.\n", __FUNCTION__);
-      goto exit;
-   }
-
-   m_HGFileContentsUriList = "";
-
-   for (i = 0; i < nFiles; i++) {
-      utf::string fileName;
-      utf::string filePathName;
-      VmTimeType createTime = -1;
-      VmTimeType accessTime = -1;
-      VmTimeType writeTime = -1;
-      VmTimeType attrChangeTime = -1;
-
-      if (!fileItem[i].cpName.cpName_val ||
-          0 == fileItem[i].cpName.cpName_len) {
-         Debug("%s: invalid fileItem[%"FMTSZ"u].cpName.\n", __FUNCTION__, i);
-         goto exit;
-      }
-
-      /*
-       * '\0' is used as directory separator in cross-platform name. Now turn
-       * '\0' in data into DIRSEPC.
-       *
-       * Note that we don't convert the final '\0' into DIRSEPC so the string
-       * is NUL terminated.
-       */
-      CPNameUtil_CharReplace(fileItem[i].cpName.cpName_val,
-                             fileItem[i].cpName.cpName_len - 1,
-                             '\0',
-                             DIRSEPC);
-      fileName = fileItem[i].cpName.cpName_val;
-      filePathName = tempDir;
-      filePathName += DIRSEPS + fileName;
-
-      if (fileItem[i].validFlags & CP_FILE_VALID_TYPE &&
-          CP_FILE_TYPE_DIRECTORY == fileItem[i].type) {
-         if (!File_CreateDirectory(filePathName.c_str())) {
-            goto exit;
-         }
-         Debug("%s: created directory [%s].\n",
-               __FUNCTION__, filePathName.c_str());
-      } else if (fileItem[i].validFlags & CP_FILE_VALID_TYPE &&
-                 CP_FILE_TYPE_REGULAR == fileItem[i].type) {
-         FileIODescriptor file;
-         FileIOResult fileErr;
-
-         FileIO_Invalidate(&file);
-
-         fileErr = FileIO_Open(&file,
-                               filePathName.c_str(),
-                               FILEIO_ACCESS_WRITE,
-                               FILEIO_OPEN_CREATE_EMPTY);
-         if (!FileIO_IsSuccess(fileErr)) {
-            goto exit;
-         }
-
-         fileErr = FileIO_Write(&file,
-                                fileItem[i].content.content_val,
-                                fileItem[i].content.content_len,
-                                NULL);
-
-         FileIO_Close(&file);
-         Debug("%s: created file [%s].\n",
-               __FUNCTION__, filePathName.c_str());
-      } else {
-         /*
-          * Right now only Windows can provide CPFORMAT_FILECONTENTS data.
-          * Symlink file is not expected. Continue with next file if the
-          * type is not valid.
-          */
-         continue;
-      }
-
-      /* Update file time attributes. */
-      createTime = fileItem->validFlags & CP_FILE_VALID_CREATE_TIME ?
-         fileItem->createTime: -1;
-      accessTime = fileItem->validFlags & CP_FILE_VALID_ACCESS_TIME ?
-         fileItem->accessTime: -1;
-      writeTime = fileItem->validFlags & CP_FILE_VALID_WRITE_TIME ?
-         fileItem->writeTime: -1;
-      attrChangeTime = fileItem->validFlags & CP_FILE_VALID_CHANGE_TIME ?
-         fileItem->attrChangeTime: -1;
-
-      if (!File_SetTimes(filePathName.c_str(),
-                         createTime,
-                         accessTime,
-                         writeTime,
-                         attrChangeTime)) {
-         /* Not a critical error, only log it. */
-         Debug("%s: File_SetTimes failed with file [%s].\n",
-               __FUNCTION__, filePathName.c_str());
-      }
-
-      /* Update file permission attributes. */
-      if (fileItem->validFlags & CP_FILE_VALID_PERMS) {
-         if (Posix_Chmod(filePathName.c_str(),
-                         fileItem->permissions) < 0) {
-            /* Not a critical error, only log it. */
-            Debug("%s: Posix_Chmod failed with file [%s].\n",
-                  __FUNCTION__, filePathName.c_str());
-         }
-      }
-
-      /*
-       * If there is no DIRSEPC inside the fileName, this file/directory is a
-       * top level one. We only put top level name into uri list.
-       */
-      if (fileName.find(DIRSEPS, 0) == utf::string::npos) {
-         m_HGFileContentsUriList += "file://" + filePathName + "\r\n";
-      }
-   }
-   Debug("%s: created uri list [%s].\n",
-         __FUNCTION__, m_HGFileContentsUriList.c_str());
-   ret = true;
-
-exit:
-   xdr_free((xdrproc_t) xdr_CPFileContents, (char *)&fileContents);
-   if (tempDir && !ret) {
-      DnD_DeleteStagingFiles(tempDir, false);
-   }
-   free(tempDir);
-   return ret;
-}
-
-
-/**
- *
- * Tell host that we are done with HG DnD initialization.
- */
-
-void
-DnDUI::SourceDragStartDone(void)
-{
-   Debug("%s: enter\n", __FUNCTION__);
-   m_inHGDrag = true;
-   m_DnD->HGDragStartDone();
-}
-
-
-/**
- * Set block control member.
- *
- * @param[in] block control as setup by vmware-user.
- */
-
-void
-DnDUI::SetBlockControl(DnDBlockControl *blockCtrl)
-{
-   m_blockCtrl = blockCtrl;
-}
-
-
-/**
- *
- * Got feedback from our DropSource, send it over to host. Called by
- * drag motion callback.
- *
- * @param[in] effect feedback to send to the UI-independent DnD layer.
- */
-
-void
-DnDUI::SourceUpdateFeedback(DND_DROPEFFECT effect)
-{
-   Debug("%s: entering\n", __FUNCTION__);
-   m_DnD->SetFeedback(effect);
-}
-
-
-/**
- *
- * This is triggered when user drags valid data from guest to host. Try to
- * get clip data and notify host to start GH DnD.
- */
-
-void
-DnDUI::TargetDragEnter(void)
-{
-   Debug("%s: entering\n", __FUNCTION__);
-
-   /* Check if there is valid data with current detection window. */
-   if (!CPClipboard_IsEmpty(&m_clipboard)) {
-      Debug("%s: got valid data from detWnd.\n", __FUNCTION__);
-      m_DnD->DragEnter(&m_clipboard);
-   }
-
-   /*
-    * Show the window, and position it under the current mouse position.
-    * This is particularly important for KDE 3.5 guests.
-    */
-   SendFakeXEvents(true, false, true, true, false, 0, 0);
-}
-
-
-/**
- *
- * Get Unix time in milliseconds. See man 2 gettimeofday for details.
- *
- * @return unix time in milliseconds.
- */
-
-unsigned long
-DnDUI::GetTimeInMillis(void)
-{
-   VmTimeType atime;
-
-   Hostinfo_GetTimeOfDay(&atime);
-   return((unsigned long)(atime / 1000));
-}
diff --git a/open-vm-tools/vmware-user/dndUI.h b/open-vm-tools/vmware-user/dndUI.h
deleted file mode 100644 (file)
index fc13566..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/**
- * @file dndUI.h
- *
- *    Implement the methods that allow DnD between host and guest for
- *    protocols V3 or greater.
- *
- */
-
-#ifndef DND_UI_H
-#define DND_UI_H
-
-#include "stringxx/string.hh"
-
-extern "C" {
-#include "debug.h"
-#include "dnd.h"
-#include "str.h"
-#include "util.h"
-#include "vmblock.h"
-#include "dndClipboard.h"
-#include "dynbuf.h"
-#include "../dnd/dndFileContentsUtil.h"
-#include "dynxdr.h"
-#include "cpNameUtil.h"
-#include "posix.h"
-}
-
-#include "dnd.hh"
-#include "dndFileList.hh"
-#include "dragDetWnd.h"
-
-struct DblLnkLst_Links;
-
-/**
- * The DnDUI class implements the UI portion of DnD V3 and greater
- * versions of the protocol.
- */
-class DnDUI
-{
-public:
-   DnDUI(DblLnkLst_Links *eventQueue);
-   ~DnDUI();
-   bool Init();
-   void VmxDnDVersionChanged(struct RpcIn *rpcIn,
-                             uint32 version)
-      {ASSERT(m_DnD); m_DnD->VmxDnDVersionChanged(rpcIn, version);}
-   void SetDnDAllowed(bool isDnDAllowed)
-      {ASSERT(m_DnD); m_DnD->SetDnDAllowed(isDnDAllowed);}
-   void SetBlockControl(DnDBlockControl *blockCtrl);
-   void SetUnityMode(Bool mode)
-      {m_unityMode = mode;};
-   void Cancel();
-
-   DragDetWnd *GetFullDetWnd() {return m_detWnd;}
-   GtkWidget *GetDetWndAsWidget();
-
-private:
-
-   /**
-    * Blocking FS Helper Functions.
-    */
-   void AddBlock();
-   void RemoveBlock();
-   bool TryXTestFakeDeviceButtonEvent(void);
-
-   /**
-    * Callbacks from Common DnD layer.
-    */
-   void CommonResetCB();
-   void CommonUpdateMouseCB(int32 x, int32 y);
-
-   /**
-    * Source functions for HG DnD.
-    */
-   void CommonDragStartCB(const CPClipboard *clip, std::string stagingDir);
-   void CommonSourceDropCB(void);
-
-   /**
-    * Called when HG Dnd is completed.
-    */
-   void CommonSourceCancelCB(void);
-
-   /**
-    * Called when GH DnD is completed.
-    */
-   void CommonDestPrivateDropCB(int32 x, int32 y);
-   void CommonDestCancelCB(void);
-
-   /**
-    * Source functions for file transfer.
-    */
-   void CommonSourceFileCopyDoneCB(bool success, std::vector<uint8> stagingDir);
-
-   /**
-    * Callbacks for showing/hiding detection window.
-    */
-   void CommonUpdateDetWndCB(bool bShow, int32 x, int32 y);
-   void CommonUpdateUnityDetWndCB(bool bShow, uint32 unityWndId, bool bottom);
-   void CommonMoveDetWndToMousePos(void);
-
-   /**
-    * Gtk+ Callbacks: Drag Destination.
-    */
-   void GtkDestDragDataReceivedCB(const Glib::RefPtr<Gdk::DragContext> &dc,
-                                  int x, int y, const Gtk::SelectionData &sd,
-                                  guint info, guint time);
-   bool GtkDestDragDropCB(const Glib::RefPtr<Gdk::DragContext> &dc,
-                          int x, int y, guint time);
-   void GtkDestDragLeaveCB(const Glib::RefPtr<Gdk::DragContext> &dc,
-                           guint time);
-   bool GtkDestDragMotionCB(const Glib::RefPtr<Gdk::DragContext> &dc, int x,
-                            int y, guint time);
-
-   /**
-    * Gtk+ Callbacks: Drag Source.
-    */
-   void GtkSourceDragBeginCB(const Glib::RefPtr<Gdk::DragContext>& context);
-   void GtkSourceDragDataGetCB(const Glib::RefPtr<Gdk::DragContext>& context,
-                               Gtk::SelectionData& selection_data, guint info,
-                               guint time);
-   void GtkSourceDragEndCB(const Glib::RefPtr<Gdk::DragContext>& context);
-   /**
-    * Source functions for HG DnD. Makes calls to common layer.
-    */
-   void SourceDragStartDone(void);
-   void SourceUpdateFeedback(DND_DROPEFFECT effect);
-
-   /**
-    * Target function for GH DnD. Makes call to common layer.
-    */
-   void TargetDragEnter(void);
-
-   /**
-    * Misc methods.
-    */
-   bool SetCPClipboardFromGtk(const Gtk::SelectionData& sd);
-   std::string GetLastDirName(const std::string &str);
-   utf::utf8string GetNextPath(utf::utf8string &str, size_t& index);
-   DND_DROPEFFECT ToDropEffect(Gdk::DragAction action);
-   void SetTargetsAndCallbacks();
-   bool SendFakeXEvents(const bool showWidget, const bool buttonEvent,
-                        const bool buttonPress, const bool moveWindow,
-                        const bool coordsProvided,
-                        const int xCoord, const int yCoord);
-   bool SendFakeMouseMove(const int x, const int y);
-   bool WriteFileContentsToStagingDir();
-   unsigned long GetTimeInMillis();
-
-   DblLnkLst_Links *m_eventQueue;
-   DnD *m_DnD;
-   std::string m_HGStagingDir;
-   utf::string m_HGFileContentsUriList;
-   DragDetWnd *m_detWnd;
-   CPClipboard m_clipboard;
-   DnDBlockControl *m_blockCtrl;
-   bool m_HGGetDataInProgress;
-   int m_HGEffect;
-   bool m_blockAdded;
-
-   /* State to determine if drag motion is a drag enter. */
-   bool m_GHDnDInProgress;
-   /* Icon updates from the guest. */
-   /* Only update mouse when we have clipboard contents from the host. */
-   bool m_GHDnDDataReceived;
-   bool m_GHDnDDropOccurred;
-   bool m_unityMode;
-   bool m_inHGDrag;
-   DND_DROPEFFECT m_effect;
-   bool m_isFileDnD;
-   int32 m_mousePosX;
-   int32 m_mousePosY;
-   GdkDragContext *m_dc;
-   unsigned long m_destDropTime;
-};
-
-#endif // DND_UI_H
diff --git a/open-vm-tools/vmware-user/dragDetWnd.cpp b/open-vm-tools/vmware-user/dragDetWnd.cpp
deleted file mode 100644 (file)
index 25f32c3..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/**
- * @file dragDetWnd.cpp
- *
- * Detection window code for Linux/X11, based on Gtkmm. Includes unit test
- * code.
- */
-
-#include "dragDetWnd.h"
-
-/**
- *
- * Constructor.
- */
-
-extern "C" {
-#include "debug.h"
-}
-
-#include "dndUI.h"
-#include <list>
-
-/**
- *
- * Constructor.
- */
-
-DragDetWnd::DragDetWnd() :
-   m_isVisible(false)
-{
-#if defined(DETWNDDEBUG)
-   DebugSetAttributes();
-#endif
-}
-
-
-/**
- *
- * Destructor.
- */
-
-DragDetWnd::~DragDetWnd()
-{
-}
-
-
-/**
- * Flush the X connection.
- */
-
-void
-DragDetWnd::Flush()
-{
-   Glib::RefPtr<Gdk::Display> gdkdisplay = Gdk::Display::get_default();
-   if (gdkdisplay) {
-      gdkdisplay->sync();
-      gdkdisplay->flush();
-   }
-}
-
-
-/**
- *
- * Show the window.
- */
-
-void
-DragDetWnd::Show(void)
-{
-   show();
-   Flush();
-}
-
-
-/**
- *
- * Hide the window.
- */
-
-void
-DragDetWnd::Hide(void)
-{
-   hide();
-   Flush();
-}
-
-
-/**
- *
- * Raise the window.
- */
-
-void
-DragDetWnd::Raise(void)
-{
-   Glib::RefPtr<Gdk::Window> gdkwin = get_window();
-   if (gdkwin) {
-      gdkwin->raise();
-   }
-   Flush();
-}
-
-
-/**
- *
- * Lower the window.
- */
-
-void
-DragDetWnd::Lower(void)
-{
-   Glib::RefPtr<Gdk::Window> gdkwin = get_window();
-   if (gdkwin) {
-      gdkwin->lower();
-   }
-   Flush();
-}
-
-
-/**
- *
- * Get the width of the screen associated with this window.
- *
- * @return width of screen, in pixels.
- */
-
-int
-DragDetWnd::GetScreenWidth(void)
-{
-   Glib::RefPtr<Gdk::Screen> gdkscreen = get_screen();
-   return gdkscreen->get_width();
-}
-
-
-/**
- *
- * Get the height of the screen associated with this window.
- *
- * @return height of screen, in pixels.
- */
-
-int
-DragDetWnd::GetScreenHeight(void)
-{
-   Glib::RefPtr<Gdk::Screen> gdkscreen = get_screen();
-   return gdkscreen->get_height();
-}
-
-
-#if defined(DETWNDDEBUG)
-/**
- *
- * Set default window attributes appropriate for debugging detection windows.
- *
- * @note This only applies to instances of DragDetWnd that are derived from
- * GTK::Window.
- */
-
-void
-DragDetWnd::DebugSetAttributes(void)
-{
-   set_default_size(1, 1);
-   set_resizable(true);
-   set_decorated(false);
-   set_type_hint(Gdk::WINDOW_TYPE_HINT_DOCK);
-}
-#endif
-
-
-/**
- *
- * Set the geometry of the window.
- *
- * @param[in] x desired x-coordinate of the window.
- * @param[in] y desired y-coordinate of the window.
- * @param[in] width desired width of the window.
- * @param[in] height desired height of the window.
- */
-
-void
-DragDetWnd::SetGeometry(const int x,
-                        const int y,
-                        const int width,
-                        const int height)
-{
-   Glib::RefPtr<Gdk::Window> gdkwin = get_window();
-
-   if (gdkwin) {
-      gdkwin->move_resize(x, y, width, height);
-      Flush();
-   }
-}
-
-
-/**
- *
- * Get the current geometry of the window.
- *
- * @param[out] x current x-coordinate of the window.
- * @param[out] y current y-coordinate of the window.
- * @param[out] width current width of the window.
- * @param[out] height current height of the window.
- *
- * @note The current geometry may be inaccurate if retrieved too quickly
- * after a change made by SetGeometry(). This is due to the realities of
- * X and window managers. Some of this is mitigated by the use of flush()
- * and sync() calls in SetGeometry(), but these are no guarantee.
- */
-
-void
-DragDetWnd::GetGeometry(int &x, int &y, int &width, int &height)
-{
-   int dummy;
-
-   Glib::RefPtr<Gdk::Window> gdkwin = get_window();
-   if (gdkwin) {
-      gdkwin->get_geometry(x, y, width, height, dummy);
-#if defined(DETWNDTEST)
-      Flush();
-#endif
-   }
-}
-
-/*
- * Code below here is for unit tests.
- */
-
-#if defined(DETWNDTEST)
-
-/**
- *
- * Add a button to launch unit tests to the drag detection window.
- */
-
-void
-DragDetWndTest::CreateTestUI()
-{
-   m_button.set_label("Start Unit Tests");
-   add(m_button);
-   m_button.signal_clicked().connect(sigc::mem_fun(*this, &DragDetWndTest::RunUnitTests));
-   m_button.show();
-}
-
-
-/**
- *
- * Run some unit tests, then exit. Requires a main program, refer to
- * bora-vmsoft/toolbox/linux/vmwareuser/detWndTest/main.cpp for an
- * example.
- */
-
-void
-DragDetWndTest::RunUnitTests()
-{
-   DragDetWnd testWnd;
-   int testCount = 0;
-   int failCount = 0;
-
-#if defined(DETWNDDEBUG)
-   testWnd.SetAttributes();
-#endif
-   testWnd.Show();
-   int x, y, width, height;
-   testWnd.GetGeometry(x, y, width, height);
-   printf("Geometry is x %d y %d width %d height %d\n", x, y, width, height);
-
-   for (int i = 10; i < 50; Gtk::Main::iteration(), i++) {
-      testCount++;
-      printf("Setting geometry to x %d y %d w %d h %d\n", i * 10, i * 10, i * 10, i * 10);
-      testWnd.SetGeometry(i * 10, i * 10, i * 10, i * 10);
-      sleep(1);
-      testWnd.GetGeometry(x, y, width, height);
-      printf("Geometry is x %d y %d width %d height %d\n", x, y, width, height);
-      if (x != i * 10 || y != i * 10 || width != i * 10) {
-         printf("FAIL x or y not correct\n");
-         failCount++;
-      }
-   }
-
-   for (int i = 49; i > 0; Gtk::Main::iteration(), i--) {
-      testCount++;
-      printf("Setting geometry to x %d y %d w %d h %d\n", i * 10, i * 10, i * 10, i * 10);
-      testWnd.SetGeometry(i * 10, i * 10, i * 10, i * 10);
-      sleep(1);
-      testWnd.GetGeometry(x, y, width, height);
-      printf("Geometry is x %d y %d width %d height %d\n", x, y, width, height);
-      if (x != i * 10 || y != i * 10 || width != i * 10) {
-         printf("FAIL width or height not correct\n");
-         failCount++;
-      }
-   }
-
-   testWnd.SetGeometry(500, 500, 300, 300);
-
-   for (int i = 0; i < 60; Gtk::Main::iteration(), i++) {
-      if (i % 2) {
-         printf("Hide\n");
-         testWnd.Hide();
-      } else {
-         printf("Show\n");
-         testWnd.Show();
-         testWnd.Raise();
-      }
-      sleep(1);
-   }
-
-   printf("Done fail count %d (%.2f%%)\n", failCount, 100.0 * failCount/testCount);
-   Gtk::Main::quit();
-}
-#endif
diff --git a/open-vm-tools/vmware-user/dragDetWnd.h b/open-vm-tools/vmware-user/dragDetWnd.h
deleted file mode 100644 (file)
index 6ee455f..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/**
- * @file dragDetWnd.h
- *
- *    Header for the DragDetWnd class.
- */
-
-#ifndef DRAG_DET_WND_H
-#define DRAG_DET_WND_H
-
-#include <gtkmm.h>
-
-#if !defined(DETWNDTEST)
-extern "C" {
-   #include "dnd.h"
-}
-#endif
-
-class DnDUI;
-
-class DragDetWnd : public Gtk::Invisible
-{
-public:
-   DragDetWnd();
-   virtual ~DragDetWnd();
-
-   void Show();
-   void Hide();
-   void Raise();
-   void Lower();
-   int GetScreenWidth();
-   int GetScreenHeight();
-   void SetGeometry(const int x, const int y,
-                    const int width, const int height);
-   void GetGeometry(int &x, int &y, int &width, int &height);
-   void SetIsVisible(const bool isVisible) {m_isVisible = isVisible;};
-   bool GetIsVisible() {return m_isVisible;};
-#if defined(DETWNDEBUG)
-   void DebugSetAttributes();
-#endif
-private:
-   void Flush();
-   bool m_isVisible;
-};
-
-#if defined(DETWNDTEST)
-class DragDetWndTest : public Gtk::Window
-{
-public:
-   void CreateTestUI();
-private:
-   virtual void RunUnitTests();
-   Gtk::Button m_button;
-};
-
-#endif
-
-#endif // DRAG_DET_WND_H
diff --git a/open-vm-tools/vmware-user/modconfig.c b/open-vm-tools/vmware-user/modconfig.c
deleted file mode 100644 (file)
index 68c4850..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/*********************************************************
- * Copyright (C) 2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * modconfig.c --
- *
- *      Handles interaction with the modconfig gui for vmware-user.
- */
-
-#include "vmwareuserInt.h"
-
-#ifdef USE_NOTIFY_DLOPEN
-
-#include "installerdb.h"
-#include "file.h"
-#include "installerdb.h"
-#include "modconf.h"
-#include "str.h"
-
-
-/*
- * Local functions
- */
-static GtkWidget *GetMenu(void);
-static void LaunchModconfig(void);
-static gboolean ActivateCallback(GtkWidget *widget, Notifier *n);
-static void MenuItemCallback(GObject *self, void *data);
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * LaunchModconfig --
- *
- *      Asynchronously spawn the modconfig process to rebuild kernel modules.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      The modoconfig program is launched, and modules are recompiled.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-LaunchModconfig(void)
-{
-   char *exePath;
-   char *command;
-   gchar *quotedExePath;
-
-   exePath = Str_Asprintf(NULL, "%s/sbin/vmware-modconfig-wrapper", vmLibDir);
-   quotedExePath = g_shell_quote(exePath);
-   command = Str_Asprintf(NULL, "%s --icon=\"vmware-modconfig\" "
-                          "--appname=\"VMware Tools\"", quotedExePath);
-
-   g_spawn_command_line_async(command, NULL);
-
-   free(command);
-   g_free(quotedExePath);
-   free(exePath);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ActivateCallback --
- *
- *      The callback invoked when the status icon is left-clicked.
- *
- * Results:
- *      TRUE if the signal is handled, FALSE otherwise.
- *
- * Side effects:
- *      Launches modconfig.
- *
- *----------------------------------------------------------------------------
- */
-
-static gboolean
-ActivateCallback(GtkWidget *widget,     // IN
-                 Notifier *n)           // IN
-{
-   LaunchModconfig();
-   return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * MenuItemCallback --
- *
- *      The callback invoked when any item on the popup context menu is clicked.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      Launches modconfig.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-MenuItemCallback(GObject *self,              // IN
-                 void *data)                 // IN
-{
-   LaunchModconfig();
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GetMenu --
- *
- *      Create the context menu for the status icon.
- *
- * Results:
- *      Returns a pointer to the created menu.
- *
- * Side effects:
- *      None.
- *
- *----------------------------------------------------------------------------
- */
-
-static GtkWidget *
-GetMenu(void)
-{
-   GtkWidget *menu = gtk_menu_new();
-   GtkWidget *menuItem = gtk_menu_item_new_with_label("Update Modules");
-   g_signal_connect(G_OBJECT(menuItem), "activate", G_CALLBACK(MenuItemCallback),
-                    NULL);
-   gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuItem);
-
-   return menu;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Modules_Init --
- *
- *      Check for kernel modules and display a notification if any are
- *      found missing.
- *
- * Results:
- *      TRUE on success, FALSE otherwise
- *
- * Side effects:
- *      A notification is displayed, informing the user of the missing
- *      modules.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Modules_Init(void)
-{
-   const char *libdir;
-   char *moduleListPath;
-   GList *modules, *modulesNotInstalled;
-
-   if (!InstallerDB_Init("/etc/vmware-tools", TRUE)) {
-      return FALSE;
-   }
-
-   /* 
-    * Only do module out-of-dateness checking if we weren't installed as
-    * a DSP.
-    */
-   if (InstallerDB_IsDSPInstall()) {
-      InstallerDB_DeInit();
-      return FALSE;
-   }
-
-   if (!ModConf_Init()) {
-      return FALSE;
-   }
-
-   libdir = InstallerDB_GetLibDir();
-   moduleListPath = g_build_filename(libdir, "modules/modules.xml", NULL);
-   modules = ModConf_GetModulesList(moduleListPath);
-   modulesNotInstalled = ModConf_GetModulesNotInstalled(modules);
-
-   if (modulesNotInstalled != NULL) {
-      Notify_Notify(30, "Kernel modules out-of-date",
-                    "It appears your kernel modules are not longer "
-                    "compatible with the running kernel.  Please "
-                    "click on the icon to recompile them.",
-                    GetMenu(), ActivateCallback);
-   }
-
-   g_list_free(modulesNotInstalled);
-   ModConf_FreeModulesList(modules);
-
-   return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Modules_Cleanup --
- *
- *      Cleanup the modconf subsystem.
- *
- * Results:
- *      TRUE on success, FALSE otherwise
- *
- * Side effects:
- *      The modconf subsystem is closed.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-Modules_Cleanup(void)
-{
-   ModConf_DeInit();
-   InstallerDB_DeInit();
-}
-
-#endif /* USE_NOTIFY_DLOPEN */
diff --git a/open-vm-tools/vmware-user/notify.c b/open-vm-tools/vmware-user/notify.c
deleted file mode 100644 (file)
index 095e68f..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-/*********************************************************
- * Copyright (C) 2008 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * notify.c --
- *
- *      Handles the system tray notifications for vmware-user.
- */
-
-#include "vmware.h"
-#include "vmwareuserInt.h"
-
-#ifdef USE_NOTIFY
-
-#include "conf.h"
-#include "debug.h"
-#include "str.h"
-
-#if defined(USE_NOTIFY_SO)
-#include <libnotify/notify.h>
-#include <libnotify/notification.h>
-#include <libnotify/NotifyNotification.h>
-#elif defined(USE_NOTIFY_DLOPEN)
-#include <dlfcn.h>
-#include <stdlib.h>
-#endif
-
-
-/*
- * Local symbols
- */
-const char *vmLibDir = NULL;
-
-#ifdef USE_NOTIFY_DLOPEN
-static gboolean (*notify_init)(const char *app_name) = NULL;
-static void (*notify_uninit)(void) = NULL;
-static NotifyNotification *(*notify_notification_new_with_status_icon)
-          (const gchar *summary, const gchar *body,
-           const gchar *icon, GtkStatusIcon *status_icon) = NULL;
-static gboolean (*notify_notification_show)(NotifyNotification *notification,
-                                            GError **error) = NULL;
-void (*notify_notification_set_timeout)(NotifyNotification *notification,
-                                        gint timeout) = NULL;
-
-static Bool LoadLibNotify(void);
-static Bool UnloadLibNotify(void);
-
-static void *libNotifyHandle = NULL;
-static Bool initialized = FALSE;
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * LoadLibNotify --
- *
- *      Dynamically load required symbols from libnotify.  We only do this
- *      when building inside the VMware tree; when shipping open-vm-tools,
- *      we can just let the linker do the work, since we have the libraries
- *      available at build-time.
- *
- * Results:
- *      TRUE on success, FALSE otherwise
- *
- * Side effects:
- *      libnotify is loaded, and symbols populated.
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-LoadLibNotify(void)
-{
-   int i;
-
-   libNotifyHandle = dlopen("libnotify.so.1", RTLD_LAZY);
-
-   if (!libNotifyHandle) {
-      return FALSE;
-   }
-
-   /* 
-    * The list of symbols we want to dynamically load from libnotify.  It
-    * must be NULL-terminated.  To load additional symbols, be sure to
-    * define them above, with file-level scope, and then add them to this
-    * list.
-    */
-   {
-      struct FuncEntry
-      {
-         void **funcPtr;
-         const char *symName;
-      } vtable[] = {
-         { (void **) &notify_init, "notify_init" },
-         { (void **) &notify_uninit, "notify_uninit" },
-         { (void **) &notify_notification_show, "notify_notification_show" },
-         { (void **) &notify_notification_new_with_status_icon,
-           "notify_notification_new_with_status_icon" },
-         { (void **) &notify_notification_set_timeout,
-           "notify_notification_set_timeout" },
-         { NULL, NULL }
-      };
-
-      /*
-       * Load each of the above symbols from libnotify, checking to make sure
-       * that they exist.
-       */
-      for (i = 0; vtable[i].funcPtr != NULL; i++) {
-         *(vtable[i].funcPtr) = dlsym(libNotifyHandle, vtable[i].symName);
-         if ( *(vtable[i].funcPtr) == NULL) {
-            Debug("Could not find %s in libnotify\n", vtable[i].symName);
-            UnloadLibNotify();
-            return FALSE;
-         }
-      }
-   }
-
-   return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnloadLibNotify --
- *
- *      Decrement the reference count for libnotify.  We only do this when
- *      building inside the VMware tree; when shipping open-vm-tools, we can
- *      just let the linker do the work, since we have the libraries
- *      available at build-time.
- *
- * Results:
- *      TRUE on success, FALSE otherwise
- *
- * Side effects:
- *      libnotify is unloaded
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-UnloadLibNotify(void)
-{
-   return dlclose(libNotifyHandle) == 0;
-}
-#endif  /* USE_NOTIFY_DLOPEN */
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Notify_Init --
- *
- *      Initializes the notification system.
- *
- * Results:
- *      TRUE on success, FALSE otherwise
- *
- * Side effects:
- *      Notification system is initialized.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Notify_Init(GuestApp_Dict *confDict)  // IN: Configuration dictionary
-{
-#ifdef USE_NOTIFY_DLOPEN
-   if (LoadLibNotify() == FALSE) {
-      return FALSE;
-   }
-#endif
-
-   vmLibDir = GuestApp_GetDictEntry(confDict, CONFNAME_LIBDIR);
-   initialized = notify_init("vmware-user");
-
-   return initialized;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Notify_Cleanup --
- *
- *      Clean up the notification system.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      Notification system is deinitialized.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-Notify_Cleanup(void)
-{
-   initialized = FALSE;
-   notify_uninit();
-
-#ifdef USE_NOTIFY_DLOPEN
-   UnloadLibNotify();
-#endif
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * PopupCallback --
- *
- *      The callback invoked when the status icon is right-clicked.
- *
- * Results:
- *      TRUE if the signal is handled, FALSE otherwise.
- *
- * Side effects:
- *      Displays the popup menu for the icon.
- *
- *----------------------------------------------------------------------------
- */
-
-static gboolean
-PopupCallback(GtkStatusIcon *statusIcon,        // IN
-              guint button,                     // IN
-              guint activateTime,               // IN
-              Notifier *n)                      // IN
-{
-   gtk_menu_set_screen(GTK_MENU(n->menu),
-                       gtk_status_icon_get_screen(n->statusIcon));
-   gtk_menu_popup(GTK_MENU(n->menu), NULL, NULL,
-                  gtk_status_icon_position_menu, n->statusIcon, button,
-                  activateTime);
-   return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Notify_Notify --
- *
- *      Create and display the notification icon with the given message.
- *
- * Results:
- *      TRUE if successful, FALSE otherwise.
- *
- * Side effects:
- *      Notification is displayed.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Notify_Notify(int secs,                  // IN: Number of seconds to display
-              const char *shortMsg,      // IN: Short summary message
-              const char *longMsg,       // IN: Longer detailed message
-              GtkWidget *menu,           // IN: Context menu
-              gboolean (*activateCallback)(GtkWidget *, Notifier *))
-                                         // IN: The left-click callback
-{
-   char *iconPath;
-   Notifier *n;
-
-   if (!initialized) {
-      return FALSE;
-   }
-
-   n = g_new0(Notifier, 1);
-   iconPath = Str_Asprintf(NULL, "%s/share/icons/vmware.png", vmLibDir);
-   n->statusIcon = gtk_status_icon_new_from_file(iconPath);
-   gtk_status_icon_set_tooltip(n->statusIcon, shortMsg);
-   gtk_status_icon_set_visible(n->statusIcon, TRUE);
-   free(iconPath);
-
-   /*
-    * Display the notification for secs seconds.
-    */
-   n->notification = notify_notification_new_with_status_icon(shortMsg, longMsg,
-                                                              NULL, n->statusIcon);
-   notify_notification_set_timeout(n->notification, secs * 1000);
-   notify_notification_show(n->notification, NULL);
-
-   /*
-    * Connect the click and right-click signals.
-    */
-   g_signal_connect(G_OBJECT(n->statusIcon), "activate",
-                    G_CALLBACK(activateCallback), n);
-   g_signal_connect(G_OBJECT(n->statusIcon), "popup-menu",
-                    G_CALLBACK(PopupCallback), n);
-
-   n->menu = menu;
-   gtk_widget_show_all(n->menu);
-
-   return TRUE;
-}
-
-#endif
diff --git a/open-vm-tools/vmware-user/pointer.c b/open-vm-tools/vmware-user/pointer.c
deleted file mode 100644 (file)
index 96da764..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * pointer.c --
- *
- *     Set of functions for pointer (mouse) grab/ungrab.
- */
-
-#include "vmwareuserInt.h"
-#include <stdlib.h>
-#include <string.h>
-
-#include "vm_assert.h"
-#include "debug.h"
-#include "str.h"
-#include "strutil.h"
-#include "guestApp.h"
-#include "eventManager.h"
-#include "vmware/guestrpc/tclodefs.h"
-
-static GuestAppAbsoluteMouseState absoluteMouseState = GUESTAPP_ABSMOUSE_UNKNOWN;
-static Bool mouseIsGrabbed;
-static uint8 gHostClipboardTries = 0;
-
-/*
- * Forward Declarations
- */
-void PointerGrabbed(void);
-void PointerUngrabbed(void);
-void PointerGetXCursorPos(int *x, int *y);
-static Bool PointerUpdatePointerLoop(void* clientData);
-
-/*
- *-----------------------------------------------------------------------------
- *
- * PointerGetXCursorPos --
- *
- *      Return the position in pixels of the X (mouse) pointer in the root
- *      window.
- *
- * Results:
- *      x and y coordinates.
- *
- * Side effects:
- *      None.
- *-----------------------------------------------------------------------------
- */
-
-void
-PointerGetXCursorPos(int *rootX, int *rootY)
-{
-   Window rootWin;
-   Window childWin;
-   int x;
-   int y;
-   unsigned int mask;
-
-   XQueryPointer(gXDisplay, gXRoot, &rootWin, &childWin, rootX, rootY, &x, &y, &mask);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * PointerSetXCursorPos
- *
- *      Set the position in pixels of the X (mouse) pointer in the root window
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-PointerSetXCursorPos(int x, int y)
-{
-   XWarpPointer(gXDisplay, None, gXRoot, 0, 0, 0, 0, x, y);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * PointerGrabbed --
- *
- *      Called when the pointer's state switches from released to grabbed.
- *      We warp the cursor to whatever position the vmx tells us, and then
- *      setup the loop which attempts to get the host clipboard.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-PointerGrabbed()
-{
-   short hostPosX;
-   short hostPosY;
-
-   GuestApp_GetPos(&hostPosX, &hostPosY);
-
-   PointerSetXCursorPos(hostPosX, hostPosY);
-   gHostClipboardTries = 9;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * PointerUngrabbed --
- *
- *      Called when the pointer's state switches from grabbed to release.
- *
- * Results:
- *      None.
- *
- * Side effects:
- *      None.
- *
- *-----------------------------------------------------------------------------
- */
-void
-PointerUngrabbed(void)
-{
-   CopyPaste_RequestSelection();
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * PointerUpdatePointerLoop  --
- *
- *      Event Manager function for tracking the mouse/pointer/clipboard state.
- *      Manage grabbed/ungrab state based on x/y data from backdoor. On the
- *      transition to grabbed, call PointerHasBeenGrabbed(). While grabbed,
- *      send guest pointer coordinates thru the backdoor. Also, make several
- *      attempts to get the host clipboard from the backdoor. When changing
- *      to ungrabbed, call PointerHasBeenUngrabbed, which will push our
- *      clipboard thru the backdoor. While ungrabbed, don't do a thing.
- *
- *      This function is queued in Event Manager only when vmx doesn't support 
- *      RPC copy/paste because newer vmx initiates copy/paste from UI through 
- *      RPC, and doesn't need cursor grab/ungrab state to start copy/paste.
- *
- * Results:
- *      TRUE.
- *
- * Side effects:
- *      Lots. The vmx's notion of guest cursor position could change, the
- *      vmx's clipboard could change, and the guest's clipboard could change.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-PointerUpdatePointerLoop(void* clientData) // IN: unused
-{
-   int16 hostX, hostY;
-   int guestX, guestY;
-
-   GuestApp_GetPos(&hostX, &hostY);
-   if (mouseIsGrabbed) {
-      if (hostX == UNGRABBED_POS) {
-         /* We transitioned from grabbed to ungrabbed */
-         mouseIsGrabbed = FALSE;
-         PointerUngrabbed();
-      } else {
-         PointerGetXCursorPos(&guestX, &guestY);
-         if (hostX != guestX || hostY != guestY) {
-            GuestApp_SetPos(guestX,guestY);
-         }
-         if (gHostClipboardTries-- > 0) {
-            if (gHostClipboardTries < 6 &&
-                CopyPaste_GetBackdoorSelections()) {
-               gHostClipboardTries = 0;
-            }
-         }
-      }
-   } else {
-      if (hostX != UNGRABBED_POS) {
-         mouseIsGrabbed = TRUE;
-         PointerGrabbed();
-      }
-
-   }
-
-   if (!CopyPaste_IsRpcCPSupported() ||
-       (absoluteMouseState == GUESTAPP_ABSMOUSE_UNAVAILABLE)) {
-      EventManager_Add(gEventQueue, POINTER_POLL_TIME, PointerUpdatePointerLoop,
-                       clientData);
-   }
-   return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Pointer_Register --
- *
- *      Initialize Pointer.
- *
- * Results:
- *      Always TRUE.
- *
- * Side effects:
- *      None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-Pointer_Register(GtkWidget* mainWnd)
-{
-   absoluteMouseState = GuestApp_GetAbsoluteMouseState();
-   PointerUpdatePointerLoop(mainWnd);
-   mouseIsGrabbed = FALSE;
-   return TRUE;
-}
diff --git a/open-vm-tools/vmware-user/vmware-user.cpp b/open-vm-tools/vmware-user/vmware-user.cpp
deleted file mode 100644 (file)
index 98cabd1..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/**
- * @file vmware-user.cpp
- *
- * The linux vmware-user app. It's a hidden window app that is supposed
- * to run on session start. It handles tools features which we want
- * active all the time, but don't want to impose a visible window on the
- * user.
- */
-
-/*
- *-----------------------------------------------------------------------------
- *
- * main --
- *
- *      This is main
- *
- * Results:
- *      Returns either EXIT_SUCCESS or EXIT_FAILURE appropriately.
- *
- * Side effects:
- *      The linux toolbox ui will run and do a variety of tricks for your
- *      amusement.
- *
- *-----------------------------------------------------------------------------
- */
-
-int
-main(int argc,         // IN
-     char *argv[],     // IN
-     char *envp[])     // IN
-{
-   return 0;
-}
diff --git a/open-vm-tools/vmware-user/vmwareuserInt.h b/open-vm-tools/vmware-user/vmwareuserInt.h
deleted file mode 100644 (file)
index af35eee..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*********************************************************
- * Copyright (C) 2005 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * vmwareuserInt.h --
- *
- *     Common defines used by vmwareuser
- */
-#ifndef _VMWAREUSER_INT_H_
-# define _VMWAREUSER_INT_H_
-
-#include <X11/Xlib.h>
-#include <X11/extensions/Xrandr.h>
-#ifndef NO_MULTIMON
-#include <X11/extensions/Xinerama.h>
-#endif
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-#undef Bool
-#include "vm_basic_types.h"
-#include "rpcout.h"
-#include "rpcin.h"
-#include "dnd.h"
-
-#include "guestApp.h"
-
-/*
- * These must be the same as the minimum values used by the lots_of_modlines()
- * function in config.pl
- */
-#define RESOLUTION_MIN_WIDTH  100
-#define RESOLUTION_MIN_HEIGHT 100
-
-#define RPCIN_POLL_TIME        10  /* in 1/1000ths of a second */
-#define POINTER_POLL_TIME      15  /* in 1/1000ths of a second */
-#define UNGRABBED_POS (-100)
-#define DEBUG_PREFIX           "vmusr"
-
-#define FCP_FILE_TRANSFER_NOT_YET            0
-#define FCP_FILE_TRANSFERRING                1
-#define FCP_FILE_TRANSFERRED                 2
-
-Bool DnD_Register(GtkWidget *hgWnd, GtkWidget *ghWnd);
-Bool DnD_RegisterCapability(void);
-void DnD_Unregister(GtkWidget *hgWnd, GtkWidget *ghWnd);
-uint32 DnD_GetVmxDnDVersion(void);
-int DnD_GetNewFileRoot(char *fileRoot, int bufSize);
-void DnD_OnReset(GtkWidget *hgWnd, GtkWidget *gHWnd);
-Bool DnD_InProgress(void);
-void DnD_SetMode(Bool unity);
-
-Bool CopyPaste_Register(GtkWidget* mainWnd);
-Bool CopyPaste_RegisterCapability(void);
-int32 CopyPaste_GetVmxCopyPasteVersion(void);
-void CopyPaste_RequestSelection(void);
-Bool CopyPaste_GetBackdoorSelections(void);
-void CopyPaste_Unregister(GtkWidget* mainWnd);
-Bool CopyPaste_GHFileListGetNext(char **fileName, size_t *fileNameSize);
-void CopyPaste_OnReset(void);
-Bool CopyPaste_InProgress(void);
-Bool CopyPaste_IsRpcCPSupported(void);
-
-Bool Pointer_Register(GtkWidget* mainWnd);
-
-#if defined(USING_AUTOCONF) && defined(HAVE_LIBNOTIFY)
-#if defined(USE_NOTIFY_DLOPEN)
-#error "USE_NOTIFY_SO and USE_NOTIFY_DLOPEN cannot be simultaneously defined"
-#endif
-
-#define USE_NOTIFY_SO
-#endif
-
-#if defined(USE_NOTIFY_SO) || defined(USE_NOTIFY_DLOPEN)
-#define USE_NOTIFY
-#endif
-
-#ifdef USE_NOTIFY
-#ifdef USE_NOTIFY_DLOPEN
-struct NotifyNotification;
-typedef struct NotifyNotification NotifyNotification;
-#endif
-
-typedef struct
-{
-   GtkStatusIcon *statusIcon;
-   NotifyNotification *notification;
-   GtkWidget *menu;
-} Notifier;
-extern const char *vmLibDir;
-
-Bool Notify_Init(GuestApp_Dict *confDict);
-void Notify_Cleanup(void);
-Bool Notify_Notify(int secs, const char *shortMsg, const char *longMsg,
-                   GtkWidget *menu,
-                   gboolean (*callback)(GtkWidget *, Notifier *));
-
-#ifdef USE_NOTIFY_DLOPEN
-Bool Modules_Init(void);
-void Modules_Cleanup(void);
-#endif
-#endif
-
-extern RpcIn *gRpcIn;
-extern Display *gXDisplay;
-extern Window gXRoot;
-extern DblLnkLst_Links *gEventQueue;
-extern GtkWidget *gUserMainWidget;
-extern DnDBlockControl gBlockCtrl;
-
-#endif // _VMWAREUSER_INT_H_
diff --git a/open-vm-tools/vmware-user/vmwareuser_version.h b/open-vm-tools/vmware-user/vmwareuser_version.h
deleted file mode 100644 (file)
index 8492115..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *********************************************************/
-
-/*
- * vmwareuser_version.h --
- *
- * Version definitions for vmware-user (non-Windows).
- */
-
-#ifndef _VMWAREUSER_VERSION_H_
-#define _VMWAREUSER_VERSION_H_
-
-/*
- * This component's version is coupled with Tools versioning. The effect
- * is that the version increments with each build, and with each Tools
- * version bump. If and when it becomes necessary to version the component
- * manually, make sure that the version is bumped any time the component or
- * its dependencies are changed.
- */
-#include "vm_tools_version.h"
-#define VMWAREUSER_VERSION_COMMAS   TOOLS_VERSION_EXT_CURRENT_CSV
-#define VMWAREUSER_VERSION_STRING   TOOLS_VERSION_EXT_CURRENT_STR
-
-#endif /* _VMWAREUSER_VERSION_H_ */