[enable_multimon="$enableval"],
[enable_multimon="yes"])
-AC_ARG_ENABLE(
- unity,
- AS_HELP_STRING(
- [--disable-unity],
- [disables Unity, enabled by default]),
- [enable_unity="$enableval"],
- [enable_unity="yes"])
-
AC_ARG_WITH(
gtk2,
AS_HELP_STRING(
[enable_tests="$enableval"],
[enable_tests="auto"])
-# If we're not going to use Gtk 2.0, disable Unity.
-if test "$with_gtk2" != "yes"; then
- enable_unity="no"
-fi
-
AM_INIT_AUTOMAKE
###
# If the user explicitly disables X11, then don't try to detect the X-related libraries
if test "$have_x" = "disabled"; then
enable_multimon="no"
- enable_unity="no"
elif test "$have_x" != "yes"; then
AC_MSG_ERROR(
[The X11 libraries were not found. Please configure without X11 (using --without-x), or install the libX11 devel package(s).])
[AC_MSG_ERROR(
[libXinerama not found. Please configure without multimon (using --disable-multimon), configure without X11 (using --without-x), or install the libXinerama devel package(s).])],
[$COMMON_XLIBS])
- else
- if test "$enable_unity" != "no"; then
- AC_MSG_WARN([Disabling Unity due to --disable-multimon.])
- enable_unity="no"
- fi
fi
AC_CHECK_LIB(
have_xcomposite="yes"
fi
- # If we're building with support for Unity, we'll need a few additional
- # libraries.
- if test "$enable_unity" != "no"; then
- # Unity needs the X11 Screen Saver extension library. It should be
- # in the same place as the X11 libraries, so no need for any fancy
- # path checking.
- AC_VMW_CHECK_X11_LIB(
- [Xss],
- [X11/extensions/scrnsaver.h],
- [XScreenSaverQueryExtension],
- [AC_MSG_ERROR([libXss or headers not found. Please configure without Unity (using --disable-unity) or install the libXss devel package.])])
-
- # Check for the uriparser library and headers. The upstream uriparser
- # doesn't appear to ship with either a pkg-config file or a
- # uriparser-config binary, so we'll look for it the old-fashioned
- # way.
- #
- # Note that we look for uriFreeQueryListA because it's a relatively
- # new symbol that our code needs (it isn't present in the uriparser
- # that shipped with Ubuntu Hardy).
- AC_VMW_DEFAULT_FLAGS([URIPARSER], [uriparser])
- AC_VMW_CHECK_LIB([uriparser],
- [URIPARSER],
- [],
- [],
- [],
- [Uri.h],
- [uriFreeQueryListA],
- [],
- [AC_MSG_ERROR([uriparser library not found or is too old. Please configure without Unity (using --disable-unity) or install the liburiparser devel package.])])
-
- # Check for libpng.
- AC_VMW_CHECK_LIB([png12],
- [LIBPNG],
- [libpng12],
- [libpng-config],
- [],
- [png.h],
- [png_access_version_number],
- [],
- [AC_MSG_ERROR([libpng not found. Please configure without Unity (using --disable-unity) or install the libpng devel package])])
-
- # Check for the zlib library and headers. Like uriparser, there
- # isn't a pkg-config or zlib-config file.
- AC_VMW_DEFAULT_FLAGS([ZLIB])
- AC_VMW_CHECK_LIB([z],
- [ZLIB],
- [],
- [],
- [],
- [zlib.h],
- [zlibVersion],
- [],
- [AC_MSG_ERROR([zlib library not found. Please configure without Unity (using --disable-unity) or install the zlib devel package.])])
-
- # Check for gio 2.24.
- AC_VMW_CHECK_LIB([gio-2.0],
- [GIO],
- [gio-unix-2.0],
- [],
- [2.24.0],
- [gio/gio.h],
- [g_desktop_app_info_get_filename],
- [],
- [AC_MSG_ERROR([GLib/GIO 2.24+ not found. Please configure without Unity (using --disable-unity) or upgrade the Glib devel package.])])
- fi # End of library checks for Unity.
-
# Check whether we have gtk+ 2.0.
if test "$with_gtk2" != "no"; then
# gdk_display_get_default_group (added in gtk+ 2.4.0) is function currently
[gdk_display_get_default_group],
[GTK_CPPFLAGS="$GTK_CPPFLAGS -DGTK2"],
[AC_MSG_ERROR([Gtk+ 2.0 library not found or too old. Please configure without Gtk+ support (using --without-gtk2) or install the Gtk+ 2.0 devel package.])])
-
- # Unity requires libgdk_pixbuf_xlib, which most systems don't seem to
- # provide via "pkg-config --libs gtk+-2.0".
- if test "$enable_unity" != "no"; then
- AC_CHECK_LIB(
- [gdk_pixbuf_xlib-2.0],
- [gdk_pixbuf_xlib_init],
- [GTK_LIBS="$GTK_LIBS -lgdk_pixbuf_xlib-2.0"],
- [AC_MSG_ERROR([gdk_pixbuf_xlib-2.0 not found. Make sure your Gtk 2.0 installation is sane, or configure without Unity (using --disable-unity).])],
- [$GTK_LIBS])
- fi
fi
#
AM_CONDITIONAL(WITH_KERNEL_MODULES, test "$with_kernel_modules" = "yes")
AM_CONDITIONAL(HAVE_XSM, test "$have_xsm" = "yes")
AM_CONDITIONAL(HAVE_XCOMPOSITE, test "$have_xcomposite" = "yes")
-AM_CONDITIONAL(ENABLE_UNITY, test "$enable_unity" = "yes")
AM_CONDITIONAL(ENABLE_TESTS, test "$have_cunit" = "yes")
AM_CONDITIONAL(WITH_ROOT_PRIVILEGES, test "$with_root_privileges" = "yes")
AM_CONDITIONAL(HAVE_DNET, test "$have_dnet" = "yes")
lib/hgfsServer/Makefile \
lib/hgfsServerManagerGuest/Makefile \
lib/hgfsServerPolicyGuest/Makefile \
- lib/image/Makefile \
lib/impersonate/Makefile \
lib/lock/Makefile \
lib/message/Makefile \
lib/panicDefault/Makefile \
lib/printer/Makefile \
lib/procMgr/Makefile \
- lib/raster/Makefile \
- lib/region/Makefile \
lib/rpcChannel/Makefile \
lib/rpcIn/Makefile \
lib/rpcOut/Makefile \
services/plugins/powerOps/Makefile \
services/plugins/resolutionSet/Makefile \
services/plugins/timeSync/Makefile \
- services/plugins/unity/Makefile \
services/plugins/vix/Makefile \
services/plugins/vmbackup/Makefile \
vmware-user-suid-wrapper/Makefile \
SUBDIRS += hgfsServer
SUBDIRS += hgfsServerManagerGuest
SUBDIRS += hgfsServerPolicyGuest
-if ENABLE_UNITY
- SUBDIRS += image
-endif
SUBDIRS += impersonate
SUBDIRS += lock
SUBDIRS += message
SUBDIRS += panicDefault
SUBDIRS += printer
SUBDIRS += procMgr
-if ENABLE_UNITY
- SUBDIRS += raster
- SUBDIRS += region
-endif
SUBDIRS += rpcChannel
SUBDIRS += rpcIn
SUBDIRS += rpcOut
+++ /dev/null
-################################################################################
-### Copyright 2008 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
-################################################################################
-
-noinst_LTLIBRARIES = libImage.la
-
-libImage_la_SOURCES =
-libImage_la_SOURCES += imageUtilPng.c
-
-AM_CFLAGS =
-AM_CFLAGS += @LIBPNG_CPPFLAGS@
-AM_CFLAGS += @ZLIB_CPPFLAGS@
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2002 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.
- *
- *********************************************************/
-
-/*
- * imageUtilPng.c --
- *
- * This file contains platform independent code to read and write PNG files
- * using libpng.
- */
-
-#include "vmware.h"
-#include "imageUtil.h"
-#include "rasterConv.h"
-#include "util.h"
-
-#include <png.h>
-#include <stdlib.h>
-
-#define PNG_HEADER_CHECK_BUF_SIZE 8
-
-typedef struct ImageUtilReadPng {
- unsigned char *data;
- unsigned int offset;
-} ImageUtilReadPng;
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ImageUtilReadPngCallback --
- *
- * Callback function for reading from a PNG file.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Fills buffer `data' by reading from the file. Note that png_error()
- * calls longjmp() so that an error will unwind the stack.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-ImageUtilReadPngCallback(png_structp png_ptr, // IN: PNG file info structure
- png_bytep data, // OUT: input buffer
- png_size_t length) // IN: byte count
-{
- ImageUtilReadPng *pngData = png_get_io_ptr(png_ptr);
- memcpy(data, pngData->data + pngData->offset, length);
- pngData->offset += (unsigned int)length;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ImageUtil_ReadPNGBuffer --
- *
- * Loads and reads the specified PNG file and returns its attributes and
- * data in the provided out parameters.
- *
- * Results:
- * TRUE if successful, FALSE otherwise.
- *
- * Side effects:
- * Reads a PNG image from memory.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-ImageUtil_ReadPNGBuffer(ImageInfo *image, // OUT
- const unsigned char *data, // IN
- size_t dataLen, // IN
- int pngReadFlags) // IN
-{
- png_structp png_ptr;
- png_infop info_ptr;
- int i, channel_depth, color_type, interlace_type, compression_type, filter_type;
- png_colorp palette;
- int num_palette = 0;
- int bytes_per_line;
- png_bytep *row_pointers = NULL;
- Bool ret = FALSE;
- ImageUtilReadPng *pngData = NULL;
- png_uint_32 width;
- png_uint_32 height;
-
- if (!image || !data || !dataLen) {
- return FALSE;
- }
-
- memset(image, 0, sizeof *image);
-
- pngData = Util_SafeCalloc(1, sizeof *pngData);
- pngData->data = (char *) data;
- pngData->offset = 0;
-
- /*
- * Do an initial check to make sure this is a PNG file. This check also
- * eliminate the case of 0-byte file due to the previous write error
- */
- if (dataLen < PNG_HEADER_CHECK_BUF_SIZE) {
- goto exit;
- }
-
- if (png_sig_cmp(pngData->data, 0, PNG_HEADER_CHECK_BUF_SIZE)) {
- goto exit;
- }
-
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-
- if (png_ptr == NULL) {
- goto exit;
- }
-
- /* Allocate/initialize the memory for image information. */
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL) {
- png_destroy_read_struct(&png_ptr, NULL, NULL);
- goto exit;
- }
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- goto exit;
- }
-
- png_set_read_fn(png_ptr, pngData, ImageUtilReadPngCallback);
-
- png_read_info(png_ptr, info_ptr);
-
- png_get_IHDR(png_ptr, info_ptr,
- &width, &height,
- &channel_depth, &color_type,
- &interlace_type, &compression_type, &filter_type);
-
- bytes_per_line = png_get_rowbytes(png_ptr, info_ptr);
-
- if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
- image->depth = 24;
- if (pngReadFlags & IMAGE_PNG_READ_KEEP_ALPHA) {
- image->bpp = 32;
- } else {
- png_set_strip_alpha(png_ptr);
-
- /* Update the bytes_per_line now that we've eliminated the alpha channel */
- png_read_update_info(png_ptr, info_ptr);
- bytes_per_line = png_get_rowbytes(png_ptr, info_ptr);
-
- png_get_IHDR(png_ptr, info_ptr,
- &width, &height,
- &channel_depth, &color_type, &interlace_type,
- &compression_type, &filter_type);
-
- image->bpp = 24;
- }
-
- } else if (color_type == PNG_COLOR_TYPE_RGB) {
- image->depth = image->bpp = 24;
- } else if (color_type == PNG_COLOR_TYPE_PALETTE) {
- /*
- * Load palette
- */
- if (channel_depth < 8) {
- png_set_packing(png_ptr);
- png_read_update_info(png_ptr, info_ptr);
- bytes_per_line = png_get_rowbytes(png_ptr, info_ptr);
- }
-
- image->depth = image->bpp = 8;
-
- png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
- ASSERT(num_palette <= 256);
-
- for (i = 0; i < num_palette; i++) {
- image->palette[i].red = palette[i].red;
- image->palette[i].green = palette[i].green;
- image->palette[i].blue = palette[i].blue;
- image->palette[i].reserved = 0;
- }
-
- image->numColors = num_palette;
- } else {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- goto exit;
- }
-
- ASSERT(image->depth != 0);
- ASSERT(image->bpp != 0);
-
- image->width = width;
- image->height = height;
- image->bytesPerLine = DWORD_ALIGN(bytes_per_line);
- image->flags = 0;
-
- /* BGR instead of RGB - Intel byte-order is backwards */
- png_set_bgr(png_ptr);
-
- /* Allocate the memory to hold the image using the fields of info_ptr. */
- image->data = Util_SafeMalloc(image->bytesPerLine * image->height);
- row_pointers = Util_SafeMalloc(sizeof *row_pointers * image->height);
-
- /* The easiest way to read the image: */
- for (i = 0; i < image->height; i++) {
- row_pointers[i] = image->data + i * (DWORD_ALIGN(bytes_per_line));
- }
-
- png_read_image(png_ptr, row_pointers);
- png_read_end(png_ptr, info_ptr);
-
-#ifdef VMX86_DEVEL
- /* Read text fields (XXX eventually read rectangle data here) */
- {
- png_text *text_ptr = NULL;
- int num_text = 0;
-
- if (png_get_text(png_ptr, info_ptr, &text_ptr, &num_text) > 0) {
- for(i = 0; i < num_text; i++) {
- fprintf(stderr, "Png text: (%s) %s\n", text_ptr[i].key,
- text_ptr[i].text);
- }
- }
- }
-#endif
-
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- ret = TRUE;
-
- exit:
- free(row_pointers);
- free(pngData);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ImageUtilDataWriteCallback
- *
- * Callback for the png library to write data into the DynBuf.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Writes data to DynBuf.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-ImageUtilDataWriteCallback(png_structp png_ptr, // IN
- png_bytep data, // IN
- png_size_t length) // IN
-{
- DynBuf *imageData = png_get_io_ptr(png_ptr);
- if (!DynBuf_Append(imageData, data, length)) {
- png_error(png_ptr, "Unable to append data");
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ImageUtil_ConstructPNGBuffer --
- *
- * Writes a PNG of the image to the DynBuf passed in. Accepts a zlib
- * compression level (0-9, 0 means no compression, -1 means "use the
- * default").
- *
- * Results:
- * TRUE if successful, FALSE otherwise.
- *
- * Side effects:
- * Allocates memory; If successful, imageData needs to be cleaned up later.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-ImageUtil_ConstructPNGBuffer(const ImageInfo *image, // IN
- const ImagePngWriteOptions *pOptions, // IN/OPT
- DynBuf *imageData) // OUT
-{
- png_structp png_ptr;
- png_infop info_ptr;
- int color_type, i;
- png_bytep data;
-
- //png_text text_ptr[1];
-#ifdef RGB_MASK
- png_color_8 sig_bit;
-#endif
-
- png_uint_32 k;
-
- int bytes_per_line;
- png_bytep *row_pointers;
- ImagePngWriteOptions options;
-
- ASSERT(image);
- ASSERT(imageData);
-
- if (!image || !imageData) {
- return FALSE;
- }
-
- if (pOptions == NULL) {
- options.zlibCompressLevel = -1;
- options.stripAlphaChannel = TRUE;
- } else {
- options = *pOptions;
- }
-
- row_pointers = malloc(sizeof *row_pointers * image->height);
- if (!row_pointers) {
- return FALSE;
- }
-
- DynBuf_Init(imageData);
-
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-
- if (png_ptr == NULL) {
- goto error;
- }
-
- /* Allocate/initialize the image information data. REQUIRED */
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL) {
- png_destroy_write_struct(&png_ptr, NULL);
- goto error;
- }
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- goto error;
- }
-
- png_set_write_fn(png_ptr, imageData, ImageUtilDataWriteCallback, NULL);
-
- if (image->bpp <= 8) {
- /*
- * Save palette
- */
- color_type = PNG_COLOR_TYPE_PALETTE;
- } else if (image->bpp == 32) {
- /*
- * Save with alpha channel
- */
- color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- } else {
- /*
- * Everything else is RGB
- */
- color_type = PNG_COLOR_TYPE_RGB;
- }
-
- png_set_IHDR(png_ptr, info_ptr, image->width, image->height, 8, color_type,
- PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
- if (options.zlibCompressLevel >= 0 && options.zlibCompressLevel <= 9) {
- png_set_compression_level(png_ptr, options.zlibCompressLevel);
- }
-
-#ifdef RGB_MASK
- /* Setup the color depths */
- sig_bit.red = COUNT_BITS(image->redMask);
- sig_bit.green = COUNT_BITS(image->greenMask);
- sig_bit.blue = COUNT_BITS(image->blueMask);
- png_set_sBIT(png_ptr, info_ptr, &sig_bit);
-
-#if 1 //We probably DO need this
- /* Shift the pixels up to a legal bit depth and fill in
- * as appropriate to correctly scale the image.
- */
- png_set_shift(png_ptr, &sig_bit);
-#endif
-#endif
-
- // BGR instead of RGB - Intel byte-order is backwards
- png_set_bgr(png_ptr);
-
- /*
- * Optionally write comments into the image, e.g.
- * text_ptr[0].key = "Title";
- * text_ptr[0].text = "Mona Lisa";
- * text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
- * png_set_text(png_ptr, info_ptr, text_ptr, 1);
- */
-
-
- /*
- * Now set up the transformations you want. Note that these are
- * all optional. Only call them if you want them.
- */
- bytes_per_line = image->bytesPerLine;
-
-#if 0
- /* pack pixels into bytes */
- png_set_packing(png_ptr);
-#endif
-
- data = image->data;
-
- if (image->bpp == 24) {
- /*
- * The image is already RGB, no need for any conversion/processing
- */
- } else if (image->bpp <= 8) {
- /*
- * Save palette
- */
- png_color palette[256];
- ASSERT(image->numColors <= 256);
-
- for (i = 0; i < image->numColors; i++) {
- palette[i].red = image->palette[i].red;
- palette[i].green = image->palette[i].green;
- palette[i].blue = image->palette[i].blue;
- }
-
- png_set_PLTE(png_ptr, info_ptr, palette, image->numColors);
- } else if (image->bpp == 32) {
- if (options.stripAlphaChannel) {
-
- /*
- * Strip the alpha channel
- */
-
- png_set_strip_alpha(png_ptr);
-
- /*
- * XXX: Following call appears to leak two allocations of 1 byte
- * each deep inside the png library via png_malloc.
- */
- png_read_update_info(png_ptr, info_ptr);
- }
- } else {
- /* XXX convert to 24 - we could try and support other modes? */
- bytes_per_line = DWORD_ALIGN(png_get_rowbytes(png_ptr, info_ptr));
-
- data = Util_SafeMalloc(bytes_per_line * image->height);
-
- Raster_ConvertPixels(data, bytes_per_line, 24,
- image->data, image->bytesPerLine,
- Raster_GetBPPDepth(image->depth, image->bpp),
- FALSE, NULL, 0, 0, 0, 0,
- image->width, image->height);
- }
-
- /* Write the file header information. REQUIRED */
- png_write_info(png_ptr, info_ptr);
-
- if ((image->bpp == 32) && options.stripAlphaChannel) {
- /* treat the alpha channel byte as filler */
- png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
- }
-
- for (k = 0; k < image->height; k++) {
- int rowIndex;
-
- if (image->flags & IMAGE_FLAG_BOTTOM_UP) {
- rowIndex = image->height - 1 - k;
- } else {
- rowIndex = k;
- }
-
- row_pointers[rowIndex] = data + k * bytes_per_line;
- }
-
- png_write_image(png_ptr, row_pointers);
-
- if (data != image->data) {
- free(data);
- }
-
- /* It is REQUIRED to call this to finish writing the rest of the file */
- png_write_end(png_ptr, info_ptr);
-
- /* if you allocated any text comments, free them here */
-
- png_destroy_write_struct(&png_ptr, &info_ptr);
-
- free(row_pointers);
-
- return TRUE;
- error:
- free(row_pointers);
- DynBuf_Destroy(imageData);
- return FALSE;
-}
-
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * imageUtil.h --
- *
- * Image manipulation routines.
- */
-
-#ifndef _IMAGEUTIL_H_
-#define _IMAGEUTIL_H_
-
-#include "vmware.h"
-#include "imageUtilTypes.h"
-#include "dynbuf.h"
-#include "unicodeTypes.h"
-
-#ifdef _WIN32
-#include "imageUtilWin32.h"
-#endif
-
-EXTERN Bool ImageUtil_ReadPNG(ImageInfo *image,
- ConstUnicode pathName,
- int pngReadFlags);
-EXTERN Bool ImageUtil_WritePNG(const ImageInfo *image,
- ConstUnicode pathName,
- const ImagePngWriteOptions *options);
-
-EXTERN Bool ImageUtil_WriteImage(const ImageInfo *image,
- ConstUnicode pathName,
- ImageType imageType);
-
-EXTERN Bool ImageUtil_ReadPNGBuffer(ImageInfo *image,
- const unsigned char *imageData,
- size_t dataLen,
- int pngReadFlags);
-EXTERN Bool ImageUtil_ConstructPNGBuffer(const ImageInfo *image,
- const ImagePngWriteOptions *options,
- DynBuf *imageData);
-EXTERN Bool ImageUtil_ConstructBMPBuffer(const ImageInfo *image, DynBuf *imageData);
-
-EXTERN void ImageUtil_FreeImageData(ImageInfo *image);
-
-EXTERN Bool ImageUtil_Combine(const ImageInfo *images, const VMPoint *origins,
- size_t n, ImageInfo *combined);
-
-EXTERN Bool ImageUtil_CropAndScaleImage(ImageInfo *image,
- VMRect srcRect,
- VMRect dstRect,
- ImageInfo *dstImage);
-
-#endif // _IMAGEUTIL_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2003 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.
- *
- *********************************************************/
-
-/*
- * imageUtilTypes.h --
- *
- */
-
-#ifndef _IMAGEUTIL_TYPES_H_
-#define _IMAGEUTIL_TYPES_H_
-
-typedef enum {
- IMAGE_TYPE_PNG,
- IMAGE_TYPE_BMP
-} ImageType;
-
-typedef enum {
- IMAGE_FLAG_TOP_DOWN = 0, /* Top-down scanlines are the default */
- IMAGE_FLAG_BOTTOM_UP = (1 << 0), /* Bottom-up storage (BMP or OpenGL style) */
-} ImageFlags;
-
-typedef struct {
- unsigned char blue;
- unsigned char green;
- unsigned char red;
- unsigned char reserved;
-} ImageColor;
-
-typedef struct {
- unsigned int width;
- unsigned int height;
-
- /*
- * 'depth' is the color depth (in bits per pixel) used for the image. 'bpp'
- * is the number of bits actually consumed per pixel in memory. (For
- * example, an image that uses 5 bits for each of R, G, B has depth=15 and
- * bpp=16. If an image has an alpha channel, the alpha bits are counted in
- * 'bpp' but not in 'depth'.) It's always true that depth <= bpp.
- *
- * Also see the comment to Raster_ConvertPixels.
- */
- unsigned int depth;
- unsigned int bpp;
- unsigned int bytesPerLine;
- ImageFlags flags;
- union {
- struct {
- unsigned int numColors;
- ImageColor palette[256];
- };
- struct {
- unsigned int redMask;
- unsigned int blueMask;
- unsigned int greenMask;
- };
- };
- unsigned char *data;
-} ImageInfo;
-
-typedef struct {
- int zlibCompressLevel; // Set to -1 for the default compression level.
- Bool stripAlphaChannel;
-} ImagePngWriteOptions;
-
-typedef enum {
- IMAGE_PNG_READ_KEEP_ALPHA = (1 << 0),
-} ImagePngReadFlags;
-
-#endif // _IMAGEUTIL_TYPES_H_
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * rasterConv.h --
- *
- * Pixel conversion routines
- */
-
-#ifndef _RASTER_CONV_H_
-#define _RASTER_CONV_H_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#include "includeCheck.h"
-
-/*
- * To minimize the amount of code needed to support the rarely-useful
- * BGR111 and BGR222 modes, their masks are defined to match the
- * appropriate number of high bits of the BGR233 masks.
- */
-
-#define REDMASK_BGR111 0x04
-#define GREENMASK_BGR111 0x20
-#define BLUEMASK_BGR111 0x80
-
-#define REDMASK_RGB222 0x30
-#define GREENMASK_RGB222 0x0c
-#define BLUEMASK_RGB222 0x03
-
-#define REDMASK_BGR222 0x03
-#define GREENMASK_BGR222 0x0c
-#define BLUEMASK_BGR222 0x30
-
-#define REDMASK_BGR233 0x07
-#define GREENMASK_BGR233 0x38
-#define BLUEMASK_BGR233 0xc0
-
-#define REDMASK_15 0x7c00
-#define GREENMASK_15 0x03e0
-#define BLUEMASK_15 0x001f
-
-#define GREEN_HIBIT_15 0x0200
-#define GREEN_HILOSHIFT_15 4
-
-#define REDMASK_16 0xf800
-#define GREENMASK_16 0x07e0
-#define BLUEMASK_16 0x001f
-
-#define REDMASK_24 0x00ff0000
-#define GREENMASK_24 0x0000ff00
-#define BLUEMASK_24 0x000000ff
-
-#define REDMASK_32 0x00ff0000
-#define GREENMASK_32 0x0000ff00
-#define BLUEMASK_32 0x000000ff
-
-Bool Raster_IsModeReasonable(uint32 depth, uint32 bpp, Bool pseudocolor);
-
-int Raster_GetBPPDepth(uint32 depth, uint32 bpp);
-
-void Raster_ConvertPixels(uint8 *tof, int32 line_increment, int bppdepth,
- const uint8 *src, int32 src_increment, int src_bppdepth,
- Bool pseudoColor, const uint32 *pixels,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h);
-
-uint32 Raster_ConvertOnePixel(uint32 pixel, int src_depth, int depth,
- Bool pseudoColor, const uint32 *pixels);
-
-Bool Raster_ConversionParameters(int depth, uint32 *redMask,
- uint32 *greenMask, uint32 *blueMask);
-
-#endif // _RASTER_CONV_H_
+++ /dev/null
-/* **********************************************************
- * Copyright (C) 2002 VMware, Inc.
- * All Rights Reserved
- * **********************************************************/
-
-/* $Xorg: regionstr.h,v 1.4 2001/02/09 02:05:15 xorgcvs Exp $ */
-/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-/* $XFree86: xc/programs/Xserver/include/regionstr.h,v 1.7 2001/12/14 19:59:56 dawes Exp $ */
-
-/*
- * region.h --
- *
- * Interface definition for miRegion operations. Originally from X11
- * source distribution. This version includes modifications made for the
- * VNC Reflector package.
- *
- * ChangeLog:
- *
- * 07/21/2003 rrdharan - added miRegionArea function prototype
- * - added REGION_AREA wrapper macro
- * - added this header, removed whitespace
- * 08/02/2005 akan - fixed conflicting definition of MINSHORT
- * and MAXSHORT with winnt.h
- * 04/03/2007 shelleygong - use int instead of short for data
- * inside the region
- * 02/12/2010 michael - Since coordinates are kept as ints, coordinate values
- * shouldn't be clamped to the range of short. I removed R_{MIN,MAX}SHORT
- * and changed clamping to be in the range R_MININT..R_MAXINT instead.
- * Since some code does "n < R_MININT" and "n > R_MAXINT", R_MININT must be
- * greater than INT_MIN and R_MAXINT must be less than INT_MAX.
- * 03/08/2010 amarp - Move xalloc macro outside the header because of
- * boost conflict with macro
- */
-
-#ifndef __REGION_H__
-#define __REGION_H__
-
-#include "vmware.h"
-
-/* Return values from RectIn() */
-#define rgnOUT 0
-#define rgnIN 1
-#define rgnPART 2
-
-#define NullBox ((BoxPtr)0)
-#define NullRegion ((RegionPtr)0)
-
-#define R_MAXINT 0x0FFFFFFF /* Must be less than INT_MAX */
-#define R_MININT 0x8FFFFFFF /* Must be greater than INT_MIN */
-
-#define CT_YXBANDED 18
-
-#define xrealloc(ptr, n) realloc((ptr), (n))
-#define xfree(ptr) free(ptr)
-
-typedef enum {
- UpdateRect,
- ROPFillRect,
- Present3dRect,
- LockRect,
- FenceRect,
- MaxRect
-} RectInfoType;
-
-typedef struct RectInfo {
- RectInfoType type;
- union {
- struct {
- uint32 rop;
- uint32 color;
- } ROPFill;
- struct {
- uint32 sid;
- uint32 srcx, srcy;
- } Present3d;
- struct {
- uint32 fenceId;
- } Fence;
- /* add more here, then update miRectInfosEqual and miPrintRegion. */
- };
-} RectInfo, *RectInfoPtr;
-
-#define RECTINFO_ISVALID(info) \
- ((info).type >= UpdateRect && (info).type < MaxRect)
-
-/*
- * X data types
- */
-
-typedef struct _Box {
- int x1, y1, x2, y2;
- RectInfo info;
-} BoxRec, *BoxPtr;
-
-typedef struct _xPoint {
- int x, y;
-} xPoint, *xPointPtr;
-
-typedef xPoint DDXPointRec, *DDXPointPtr;
-
-typedef struct _xRectangle {
- int x, y;
- unsigned short width, height;
- RectInfo info;
-} xRectangle, *xRectanglePtr;
-
-/*
- * clip region
- */
-
-typedef struct _RegData {
- int size;
- int numRects;
-/* BoxRec rects[size]; in memory but not explicitly declared */
-} RegDataRec, *RegDataPtr;
-
-typedef struct _Region {
- BoxRec extents;
- RegDataPtr data;
-} RegionRec, *RegionPtr;
-
-extern BoxRec miEmptyBox;
-extern RegDataRec miEmptyData;
-extern RegDataRec miBrokenData;
-
-#define REGION_EXTENTS(reg) (&(reg)->extents)
-#define REGION_NIL(reg) ((reg)->data && !(reg)->data->numRects)
-#define REGION_NAR(reg) ((reg)->data == &miBrokenData)
-#define REGION_NUM_RECTS(reg) ((reg)->data ? (reg)->data->numRects : 1)
-#define REGION_SIZE(reg) ((reg)->data ? (reg)->data->size : 0)
-#define REGION_RECTS(reg) ((reg)->data ? (BoxPtr)((reg)->data + 1) \
- : &(reg)->extents)
-#define REGION_BOXPTR(reg) ((BoxPtr)((reg)->data + 1))
-#define REGION_BOX(reg,i) (®ION_BOXPTR(reg)[i])
-#define REGION_TOP(reg) REGION_BOX(reg, (reg)->data->numRects)
-#define REGION_END(reg) REGION_BOX(reg, (reg)->data->numRects - 1)
-#define REGION_SZOF(n) (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)))
-
-#define REGION_VALIDINDEX(reg, i) (i >= 0 && i < REGION_NUM_RECTS((reg)))
-
-#define BOX_X(ptr) (ptr->x1)
-#define BOX_Y(ptr) (ptr->y1)
-#define BOX_WIDTH(ptr) (ptr->x2 - ptr->x1)
-#define BOX_HEIGHT(ptr) (ptr->y2 - ptr->y1)
-#define BOX_XY(ptr) BOX_X(ptr), BOX_Y(ptr)
-#define BOX_WH(ptr) BOX_WIDTH(ptr), BOX_HEIGHT(ptr)
-#define BOX_XYWH(ptr) BOX_XY(ptr), BOX_WH(ptr)
-
-#define RECT_SETBOX(r, rx, ry, rw, rh) do { \
- (r)->x1 = (rx); \
- (r)->x2 = (rx) + (rw); \
- (r)->y1 = (ry); \
- (r)->y2 = (ry) + (rh); \
- (r)->info.type = UpdateRect; \
-} while (FALSE)
-
-#define RECT_SETRECT(r, rx1, ry1, rx2, ry2) do { \
- RECT_SETBOX((r), (rx1), (ry1), ((rx2) - (rx1)), ((ry2) - (ry1))); \
-} while (FALSE)
-
-#define RECT_SETVMRECT(r, vmr) \
- RECT_SETRECT((r), (vmr)->left, (vmr)->top, (vmr)->right, (vmr)->bottom)
-
-/*
- * This will only work if the intersection is not empty.
- */
-#define RECT_INTERSECT(r, r1, r2) \
-{ \
- (r)->x1 = MAX((r1)->x1, (r2)->x1); \
- (r)->x2 = MIN((r1)->x2, (r2)->x2); \
- (r)->y1 = MAX((r1)->y1, (r2)->y1); \
- (r)->y2 = MIN((r1)->y2, (r2)->y2); \
-}
-
-/*
- * True iff the two boxes overlap.
- */
-#define RECT_EXTENTCHECK(r1, r2) \
- (!( ((r1)->x2 <= (r2)->x1) || \
- ((r1)->x1 >= (r2)->x2) || \
- ((r1)->y2 <= (r2)->y1) || \
- ((r1)->y1 >= (r2)->y2) ) )
-
-/*
- * True iff both the BoxRecs are identical.
- */
-#define RECT_IDENTICAL(r1, r2) \
- (( ((r1)->x1 == (r2)->x1) && \
- ((r1)->x2 == (r2)->x2) && \
- ((r1)->y1 == (r2)->y1) && \
- ((r1)->y2 == (r2)->y2) ) )
-
-
-extern RegionPtr miRegionCreate(BoxPtr rect, int size);
-extern void miRegionInit(RegionPtr pReg, BoxPtr rect, int size);
-extern void miRegionDestroy(RegionPtr pReg);
-extern void miRegionUninit(RegionPtr pReg);
-extern Bool miRegionCopy(RegionPtr dst, RegionPtr src);
-extern Bool miIntersect(RegionPtr newReg, RegionPtr reg1, RegionPtr reg2);
-extern Bool miUnion(RegionPtr newReg, RegionPtr reg1, RegionPtr reg2);
-extern Bool miRegionAppend(RegionPtr dstrgn, RegionPtr rgn);
-extern Bool miRegionValidate(RegionPtr badreg, Bool *pOverlap);
-extern RegionPtr miRectsToRegion(int nrects, xRectanglePtr prect, int ctype);
-extern RegionPtr miRectsToRegionbyBoundary(int nrects, xRectanglePtr prect, int ctype,
- int minValue, int maxValue);
-extern Bool miSubtract(RegionPtr regD, RegionPtr regM, RegionPtr regS);
-extern Bool miInverse(RegionPtr newReg, RegionPtr reg1, BoxPtr invRect);
-extern int miRectIn(RegionPtr region, BoxPtr prect);
-extern void miTranslateRegion(RegionPtr pReg, int x, int y);
-extern void miTranslateRegionByBoundary(RegionPtr pReg, int x, int y,
- int minValue, int maxValue);
-extern void miRegionReset(RegionPtr pReg, BoxPtr pBox);
-extern Bool miRegionBreak(RegionPtr pReg);
-extern Bool miPointInRegion(RegionPtr pReg, int x, int y, BoxPtr box);
-extern Bool miRegionNotEmpty(RegionPtr pReg);
-extern void miRegionEmpty(RegionPtr pReg);
-extern Bool miRegionsEqual(RegionPtr reg1, RegionPtr reg2);
-extern BoxPtr miRegionExtents(RegionPtr pReg);
-extern int miRegionArea(RegionPtr pReg);
-extern void miRegionPack(RegionPtr pReg, int threshold);
-
-extern Bool miApplyRect(RegionPtr newReg, RegionPtr reg, BoxPtr rect,
- Bool (*op) (RegionPtr, RegionPtr, RegionPtr));
-extern int miPrintRegion(RegionPtr rgn);
-
-typedef Bool (*miRegionMatchFunc)(BoxPtr box, uintptr_t userData);
-extern Bool miRegionMatch(RegionPtr newReg, RegionPtr reg,
- miRegionMatchFunc match, uintptr_t userData);
-
-// Extension to REGION_NIL that also checks for a 0 x 0 bounding rect.
-extern Bool miIsRegionVoid(RegionPtr pReg);
-
-#endif /* __REGION_H__ */
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/**
- * @file unityCommon.h
- *
- * Data shared between Tools, VMX, and UI for Unity
- * RPCs, attributes, and variables.
- */
-
-/*
- * Breakdown of components involved in Unity:
- *
- * 1) Unity desktop target
- *
- * This is the system on which Unity windows will be displayed.
- *
- * Currently, the host operating system running VMware Workstation
- * or Fusion.
- *
- * 2) Unity desktop source
- *
- * This is the system from which windows will be read and
- * enumerated, and sent over to the Unity desktop target.
- *
- * An agent running on the desktop source will gather
- * enumerated window data and send it to the Unity server.
- *
- * Currently, the virtualized guest operating system running
- * under Workstation or Fusion, and VMware Tools running on that
- * operating system.
- *
- * Source: bora-vmsoft/lib/unity
- * bora/lib/unityWindowTracker
- *
- * 3) Unity client
- *
- * This is a VNC-capable client that supports the extensions
- * specified in VNCEncode_UnitySupported.
- *
- * Source: bora/apps/lib/cui/unityMgr.cc
- * bora/apps/lib/cui/unityMgrVNC.cc
- * bora/lib/vnc/vncDecode.c
- *
- * (used by the Workstation and Fusion hosted UI
- * processes)
- *
- * 4) Unity server
- *
- * This is a VNC server that recognizes the Unity VNC extensions
- * and handles instructing the agent running on the Unity desktop
- * source to enumerate its windows and update the server with
- * window metadata (geometry, title, shaped region, etc.)
- *
- * The Unity server gathers window metadata in its own Unity
- * window tracker to decide what data to send to the Unity
- * client.
- *
- * Source: bora/lib/unityWindowTracker
- * bora/mks/hostops/vncBackend.c
- * bora/lib/vnc/vncEncode.c
- *
- * (used by the VMX process)
- *
- */
-
-/*
- * Overview of Unity enter operation
- * ---------------------------------
- *
- * This is an idealized order of operations between the Unity
- * client, server, and agent running on the Unity desktop source.
- *
- * Below the diagram are notes ([1], [2], [3]...) on the current
- * implementation (VMware Workstation and Fusion).
- *
- * In the current implementation:
- *
- * "Client" is the hosted UI process
- * "Server" is the vmware-vmx process
- * "Agent" is the vmware-user process (VMware Tools per-user process)
- *
- * /--------\ /--------\ /-------\
- * | Client | | Server | | Agent |
- * \--------/ \--------/ \-------/
- *
- * [1] RPC to start Unity
- * mode in desktop source
- * =========================>
- *
- * [2] RPC to start enumerating
- * windows of Unity desktop
- * source (aka "Unity mode")
- * =============================>
- *
- * [3] RPC response with full update
- * containing window metadata
- * of Unity desktop source
- * <=============================
- *
- * [4] RPC response with
- * Unity mode entered
- * successfully
- * <======================
- *
- * [5] Full update containing
- * window metadata of Unity
- * desktop source
- * <======================
- *
- * [6] Repeating RPC updates with /->-\
- * deltas for window metadata | |
- * of Unity desktop source | |
- * <============================= \-<-/
- *
- * [7] Delta update containing
- * window metadata of Unity
- * desktop source
- * <======================
- *
- *
- * -----------------------------------------------------------------------
- *
- * [1] Hosted UI opens VNC connection to VMX (through authd) with supported
- * encodings of at least what VNCEncode_UnitySupported requires.
- *
- * MKS remote manager receives VNC connection socket connection
- * and spins up MKS hostops VNC backend.
- *
- * [2] MKSRemoteMgr_StartUnityNotifications() asks Tools to start
- * Unity by sending two TCLO RPCs via the backdoor (TODO: failure
- * is currently ignored):
- *
- * 2a) UNITY_RPC_ENTER
- * 2b) UNITY_RPC_GET_UPDATE_FULL
- *
- * [3] Tools receives UNITY_RPC_ENTER, spins up window update thread,
- * and creates Unity window tracker. System settings and features not
- * compatible with or conducive to Unity mode, such as screen savers
- * and miscellaneous visual effects, are disabled for the duration of
- * the Unity session. (See UnityPlatformSaveSystemSettings.)
- *
- * [4] Tools sends a UNITY_RPC_UNITY_ACTIVE (state change) RPC to the host
- * indicating that it has successfully entered Unity mode. This is
- * then recorded in VMDB under "vmx/guestTools/currentStatus/unityActive".
- *
- * [5] Tools receives UNITY_RPC_GET_UPDATE_FULL, and in response enumerates
- * all windows running in the guest operating system. Windows suitable*
- * for display in Unity mode are inserted into the Unity window tracker.
- * Tools then returns the contents of the Unity window tracker as its
- * response to the RPC.
- *
- * * Examples of suitable windows are application windows, tooltips,
- * and menus. Examples of non-suitable windows are the desktop window,
- * taskbar(s) (depending on configuration), and trays.
- *
- * [6] Tools continually reacts to changes in the guest operating system's
- * windowing environment* and transforms them into input for the Unity
- * window tracker. In response to certain events, Tools will flush the
- * tracker's contents to the host via the RpcOut mechanism over the
- * backdoor. Updates will be stored in a simple queue for step [7].
- *
- * * Example windowing events are window creation and deletion, move
- * and resize.
- *
- * [7] The MKS remote manager periodically dequeues the guest's Unity window
- * updates as part of its MKSRemoteMgr_FastPoll loop. The updates are then
- * fed into the MKS's own Unity window tracker. The MKS Unity window
- * tracker then coalesces window updates and transforms them into VNC
- * rectangle updates for consumption by the UI.
- */
-
-#ifndef _UNITY_COMMON_H_
-#define _UNITY_COMMON_H_
-
-#include "vmware.h"
-
-#define UNITY_MAX_SETTOP_WINDOW_COUNT 100
-
-/*
- * Unity, GHI GuestRPC interface.
- */
-
-
-/**
- * @name Unity RPCs: Host-to-Guest
- * @{
- * @attention Any changes to this list @e must be reflected in the detailed
- * docblock(s) below.
- */
-#define UNITY_RPC_ENTER "unity.enter"
-#define UNITY_RPC_GET_UPDATE "unity.get.update"
-#define UNITY_RPC_GET_WINDOW_PATH "unity.get.window.path"
-#define UNITY_RPC_GET_BINARY_INFO "unity.get.binary.info"
-#define UNITY_RPC_GET_BINARY_HANDLERS "unity.get.binary.handlers"
-#define UNITY_RPC_OPEN_LAUNCHMENU "unity.launchmenu.open"
-#define UNITY_RPC_GET_LAUNCHMENU_ITEM "unity.launchmenu.get.item"
-#define UNITY_RPC_CLOSE_LAUNCHMENU "unity.launchmenu.close"
-#define UNITY_RPC_WINDOW_SETTOP "unity.window.settop"
-#define UNITY_RPC_WINDOW_CLOSE "unity.window.close"
-#define UNITY_RPC_GET_WINDOW_CONTENTS "unity.get.window.contents"
-#define UNITY_RPC_GET_ICON_DATA "unity.get.icon.data"
-#define UNITY_RPC_EXIT "unity.exit"
-#define UNITY_RPC_GET_UPDATE_FULL "unity.get.update.full"
-#define UNITY_RPC_GET_UPDATE_INCREMENTAL "unity.get.update.incremental"
-#define UNITY_RPC_SHELL_OPEN "unity.shell.open"
-#define UNITY_RPC_SHOW_TASKBAR "unity.show.taskbar"
-#define UNITY_RPC_WINDOW_MOVE_RESIZE "unity.window.move_resize"
-#define UNITY_RPC_DESKTOP_WORK_AREA_SET "unity.desktop.work_area.set"
-#define UNITY_RPC_WINDOW_SHOW "unity.window.show"
-#define UNITY_RPC_WINDOW_HIDE "unity.window.hide"
-#define UNITY_RPC_WINDOW_MINIMIZE "unity.window.minimize"
-#define UNITY_RPC_WINDOW_UNMINIMIZE "unity.window.restore"
-#define UNITY_RPC_WINDOW_MAXIMIZE "unity.window.maximize"
-#define UNITY_RPC_WINDOW_UNMAXIMIZE "unity.window.unmaximize"
-#define UNITY_RPC_DESKTOP_CONFIG_SET "unity.desktop.config.set"
-#define UNITY_RPC_DESKTOP_ACTIVE_SET "unity.desktop.active.set"
-#define UNITY_RPC_WINDOW_DESKTOP_SET "unity.window.desktop.set"
-#define UNITY_RPC_SET_OPTIONS "unity.set.options"
-#define UNITY_RPC_WINDOW_STICK "unity.window.stick"
-#define UNITY_RPC_WINDOW_UNSTICK "unity.window.unstick"
-#define UNITY_RPC_CONFIRM_OPERATION "unity.operation.confirm"
-#define UNITY_RPC_WINDOW_CONTENTS_REQUEST "unity.window.contents.request"
-#define UNITY_RPC_REGISTER_PBRPCSERVER "unity.register.pbrpcserver"
-#define UNITY_RPC_SEND_MOUSE_WHEEL "unity.sendMouseWheel"
-
-#define GHI_RPC_GUEST_SHELL_ACTION "ghi.guest.shell.action"
-#define GHI_RPC_SET_GUEST_HANDLER "ghi.guest.handler.set"
-#define GHI_RPC_RESTORE_DEFAULT_GUEST_HANDLER "ghi.guest.handler.restoreDefault"
-#define GHI_RPC_OUTLOOK_SET_TEMP_FOLDER "ghi.guest.outlook.set.tempFolder"
-#define GHI_RPC_OUTLOOK_RESTORE_TEMP_FOLDER "ghi.guest.outlook.restore.tempFolder"
-#define GHI_RPC_TRAY_ICON_START_UPDATES "ghi.guest.trayIcon.startUpdates"
-#define GHI_RPC_TRAY_ICON_STOP_UPDATES "ghi.guest.trayIcon.stopUpates"
-#define GHI_RPC_TRAY_ICON_SEND_EVENT "ghi.guest.trayIcon.sendEvent"
-#define GHI_RPC_SET_FOCUSED_WINDOW "ghi.guest.setFocusedWindow"
-#define GHI_RPC_GET_EXEC_INFO_HASH "ghi.guest.getExecInfoHash"
-#define GHI_RPC_AUTOLOGON_REQUIREMENTS "ghi.guest.autologon.requirements"
-#define GHI_RPC_AUTOLOGON_SET "ghi.guest.autologon.set"
-#define GHI_RPC_AUTOLOGON_QUERY "ghi.guest.autologon.query"
-#define GHI_RPC_AUTOLOGON_CLEAR "ghi.guest.autologon.clear"
-/* @} */
-
-
-/**
- * @name Unity RPCs: Guest-to-Host
- * @{
- * @attention Any changes to this list @e must be reflected in the detailed
- * docblock(s) below.
- */
-#define UNITY_RPC_PUSH_UPDATE_CMD "tools.unity.push.update"
-#define UNITY_RPC_VMX_SHOW_TASKBAR "vmx.unity.show.taskbar"
-#define UNITY_RPC_UNITY_CAP "tools.capability.unity"
-#define UNITY_RPC_SHOW_TASKBAR_CAP "tools.capability.unity.taskbar"
-#define UNITY_RPC_UNITY_ACTIVE "unity.active"
-#define GHI_RPC_LAUNCHMENU_CHANGE "tools.ghi.launchmenu.change"
-#define GHI_RPC_PROTOCOL_HANDLER_INFO "tools.ghi.protocolhandler.info"
-#define GHI_RPC_TRAY_ICON_UPDATE "ghi.guest.trayIcon.update"
-#define GHI_RPC_HOST_SHELL_ACTION "ghi.host.shell.action"
-#define UNITY_RPC_REQUEST_OPERATION "unity.operation.request"
-#define UNITY_RPC_ACK_OPERATION "unity.operation.ack"
-#define UNITY_RPC_WINDOW_CONTENTS_START "unity.window.contents.start"
-#define UNITY_RPC_WINDOW_CONTENTS_CHUNK "unity.window.contents.chunk"
-#define UNITY_RPC_WINDOW_CONTENTS_END "unity.window.contents.end"
-
-/* @} */
-
-
-/**
- * @name Unity start menus
- * @{
- * @todo Someone with GHI clue needs to correctly document these.
- *
- * Currently we have four possible unity start menu roots.
- *
- * @li @ref UNITY_START_MENU_LAUNCH_FOLDER is for all guest start menu
- * 'Programs' items plus favorite items from guest start menu folder.
- *
- * @li @ref UNITY_START_MENU_FIXED_FOLDER is for special items like 'My
- * Computer', 'My Documents', 'Control Panel', etc.
- *
- * @li @ref UNITY_START_MENU_ALL_HANDLERS_FOLDER is for all the applications
- * that are known by the guest to open files.
- *
- * @li @ref UNITY_START_MENU_RESOLVED_LAUNCH_FOLDER is the same contents as
- * @ref UNITY_START_MENU_LAUNCH_FOLDER however each item that is a shortcut
- * (link) is resolved into its destination path.
- *
- * @li @ref UNITY_START_MENU_RECENT_DOCUMENTS_FOLDER is the list of recently
- * used documents for the guest.
- */
-#define UNITY_START_MENU_LAUNCH_FOLDER "VMGuestLaunchItems"
-#define UNITY_START_MENU_FIXED_FOLDER "VMGuestFixedItems"
-#define UNITY_START_MENU_ALL_HANDLERS_FOLDER "VMGuestAllHandlers"
-#define UNITY_START_MENU_RESOLVED_LAUNCH_FOLDER "VMGuestResolvedItems"
-#define UNITY_START_MENU_RECENT_DOCUMENTS_FOLDER "VMGuestRecentDocuments"
-/* @} */
-
-#define UNITY_START_MENU_FLAG_USE_PROGRAMS_FOLDER_AS_ROOT 1
-
-/*
- * Type definitions
- */
-
-/**
- * @brief Tray icon event identifiers. See ghiTrayIcon.x.
- *
- * @note These identifiers are shared between tools and the VMX. For
- * compatibility reasons, new events must be added at the end of this
- * list, and existing event numbers should not be reused if an event
- * is removed.
- */
-
-#define GHI_TRAY_ICON_EVENT_INVALID 0
-#define GHI_TRAY_ICON_EVENT_LBUTTONDBLCLK 1
-#define GHI_TRAY_ICON_EVENT_RIGHT_CLICK 2
-#define GHI_TRAY_ICON_EVENT_LEFT_CLICK 3
-
-/**
- * @brief Opaque Unity window identifier.
- *
- * UnityWindowIds are chosen by (and only have meaning to) the guest.
- */
-typedef uint32 UnityWindowId;
-
-/**
- * @brief Unity desktop identifier.
- *
- * Starting from @c 0, references a particular Unity desktop.
- * @note A window with a @c UnityDesktopId of -1 once meant that the window was
- * sticky. This convention is deprecated in favor of
- * @ref UNITY_WINDOW_ATTR_STICKY.
- */
-typedef int32 UnityDesktopId;
-
-
-/**
- * @name Unity window states
- * @{
- * @deprecated These are deprecated in favor of window attributes and window
- * types, and are retained for compatibility purposes only.
- */
-#define UNITY_WINDOW_STATE_MINIMIZED (1 << 0)
-#define UNITY_WINDOW_STATE_IN_FOCUS (1 << 1)
-#define UNITY_WINDOW_STATE_TOPMOST (1 << 2)
-/* @} */
-
-
-/**
- * @brief Unity window attributes
- *
- * Unity window attributes are boolean flags that can be set in combination on a window.
- * If they are not set by the guest, it is up to the host to decide on a reasonable
- * default.
- */
-typedef enum {
- UNITY_WINDOW_ATTR_BORDERLESS = 0, ///< @deprecated
- UNITY_WINDOW_ATTR_MINIMIZABLE = 1, ///< Can be minimized.
- UNITY_WINDOW_ATTR_MAXIMIZABLE = 2, ///< Can be maximized.
- UNITY_WINDOW_ATTR_MAXIMIZED = 3, /**< Is maximized. @note Not mutually exclusive
- with @ref UNITY_WINDOW_STATE_MINIMIZED. */
- UNITY_WINDOW_ATTR_CLOSABLE = 5, ///< Supports closing.
- UNITY_WINDOW_ATTR_HAS_TITLEBAR = 6, ///< @deprecated
- UNITY_WINDOW_ATTR_VISIBLE = 7, ///< @deprecated
- UNITY_WINDOW_ATTR_CHILD_WINDOW = 8, ///< @deprecated
- UNITY_WINDOW_ATTR_HAS_TASKBAR_BTN = 9, /**< Should appear in the taskbar.
- @todo Consider deprecation? */
- UNITY_WINDOW_ATTR_MOVABLE = 10, ///< Can be moved around the desktop.
- UNITY_WINDOW_ATTR_RESIZABLE = 11, ///< Can be resized.
- UNITY_WINDOW_ATTR_ALWAYS_ABOVE = 12, ///< Should stay on top of stack.
- UNITY_WINDOW_ATTR_ALWAYS_BELOW = 13, ///< Should stay at bottom of stack.
- UNITY_WINDOW_ATTR_DISABLED = 14, ///< Keyboard, mouse input is disabled.
- UNITY_WINDOW_ATTR_NOACTIVATE = 15, /**< Does not raise to foreground via mouse
- click, alt-tab, etc. */
- UNITY_WINDOW_ATTR_SYSMENU = 16, /**< Window includes system menu (e.g., on
- Windows, right-click the taskbar
- button). */
- UNITY_WINDOW_ATTR_TOOLWINDOW = 17,
- UNITY_WINDOW_ATTR_APPWINDOW = 18, /**< Application window. Should appear in
- task switchers, etc. */
- UNITY_WINDOW_ATTR_FULLSCREENABLE = 19, ///< @deprecated
- UNITY_WINDOW_ATTR_FULLSCREENED = 20, ///< @deprecated
- UNITY_WINDOW_ATTR_ATTN_WANTED = 21, ///< Application wants user's attention.
- UNITY_WINDOW_ATTR_SHADEABLE = 22, ///< @deprecated
- UNITY_WINDOW_ATTR_SHADED = 23, ///< @deprecated
- UNITY_WINDOW_ATTR_STICKABLE = 24, ///< Can be made sticky.
- UNITY_WINDOW_ATTR_STICKY = 25, ///< Window should appear on all desktops.
- UNITY_WINDOW_ATTR_MODAL = 26, /**< Modal window.
- @todo But relative to which app? */
-
- UNITY_MAX_ATTRIBUTES ///< Final, sentinel attribute entry.
-} UnityWindowAttribute;
-
-typedef enum {
- UNITY_WINDOW_TYPE_NONE = -1,
- UNITY_WINDOW_TYPE_NORMAL = 0,
- UNITY_WINDOW_TYPE_PANEL,
- UNITY_WINDOW_TYPE_DIALOG,
- UNITY_WINDOW_TYPE_MENU,
- UNITY_WINDOW_TYPE_TOOLTIP,
- UNITY_WINDOW_TYPE_SPLASH,
- UNITY_WINDOW_TYPE_TOOLBAR,
- UNITY_WINDOW_TYPE_DOCK,
- UNITY_WINDOW_TYPE_DESKTOP,
- UNITY_WINDOW_TYPE_COMBOBOX,
- UNITY_WINDOW_TYPE_WIDGET,
-
- UNITY_MAX_WINDOW_TYPES // Not a valid window type
-} UnityWindowType;
-
-typedef enum {
- UNITY_ICON_TYPE_MAIN = 0,
-
- UNITY_MAX_ICONS // Not a valid icon type
-} UnityIconType;
-
-typedef uint32 UnityIconSize; // Number of pixels on the larger side of the icon (which is usually square anyways).
-#define UNITY_MAX_ICON_DATA_CHUNK ((1 << 16) - 100) // 64k, minus space for a few other return values
-
-#define UNITY_DEFAULT_COLOR "#c0c0c0"
-
-/*
- * List of operations that can be interlocked with the host, via a request, confirm,
- * acknowledge sequence of RPCs.
- */
-typedef enum {
- MINIMIZE = 1
-} UnityOperations;
-
-
-/*
- * List of features (as a bitmask) which may be optionally enabled when entering
- * Unity mode. By default all these features are disabled.
- */
-typedef enum {
- UNITY_ADD_HIDDEN_WINDOWS_TO_TRACKER = 1,
- UNITY_INTERLOCK_MINIMIZE_OPERATION = 1 << 1,
- UNITY_SEND_WINDOW_CONTENTS = 1 << 2,
- UNITY_DISABLE_COMPOSITING_IN_GUEST = 1 << 3
-} UnityFeatures;
-
-
-/*
- * UNITY_RPC_REGISTER_PBRPCSERVER includes an enumerated Address Family to distinguish
- * between PBRPC servers listening on TCP/IP sockets and those listening on VSockets.
- */
-typedef enum {
- InvalidAddressFamily = 0,
- VSocketAddressFamily = 1,
- INET4AddressFamily = 2
-} UnityPBRPCAddressFamily;
-
-
-/*
- * Multipage Doxygen documentation.
- */
-
-
-/**
- @defgroup UnityRpcHG Unity RPCs: Host-to-Guest
- @{
-
- @def UNITY_RPC_ENTER
- @brief Tell the guest to go into Unity mode.
- @code
- UNITY_RPC_ENTER
- @endcode
- @note On success, the guest will send @ref UNITY_RPC_UNITY_ACTIVE
- with an argument of @c 1 to indicate it is in Unity mode.
-
-
- @def UNITY_RPC_GET_UPDATE
- @brief Get an incremental or full update of window changes detected by
- the guest.
- @todo Deprecate this RPC in favor of using UNITY_RPC_GET_UPDATE_FULL
- and UNITY_RPC_GET_UPDATE_INCREMENTAL
- @code
- UNITY_RPC_GET_UPDATE ["incremental"]
- @endcode
- @param incremental If present, do an incremental update, otherwise full.
- @note A full update reports all current state of all windows,
- while incremental sends updates received since the last
- UNITY_RPC_GET_UPDATE was received.
- @return See @ref UnityGetUpdateReturn.
-
-
- @def UNITY_RPC_GET_WINDOW_PATH
- @brief Return keys which uniquely identify a window and its owning
- application.
- @code
- UNITY_RPC_GET_WINDOW_PATH UnityWindowId
- @endcode
- @param UnityWindowId window to get path information from
- @return
-@verbatim
-retval ::= windowPath '\0' execPath '\0' '\0'
-windowPath ::= ? UTF-8 string tying UnityWindowId to an executable ?
-execPath ::= ? UTF-8 string uniquely identifying JUST the executable ?
-@endverbatim
- @note Clients are to treat the returned paths @e only as unique
- binary keys.
- @sa UNITY_RPC_SHELL_OPEN
-
-
- @def UNITY_RPC_GET_BINARY_INFO
- @brief Return a list of icons for a window.
- @todo Move this into a GHI-specific header.
- @todo Give this RPC command an intuitive name.
- @code
- UNITY_RPC_GET_BINARY_INFO windowPath
- @endcode
- @param[in] windowPath UTF-8 encoded "window path" returned by
- @ref UNITY_RPC_GET_WINDOW_PATH.
- @return
- @verbatim
-<retval> := <name><nul><count><nul><icon_data>{<icon_data>}
-
-<name> := name of application
-<count> := number of icons returned
-<icon_data> := width<nul>height<nul>bgraSize<nul>bgraData<nul>
-<nul> := '\0'
-@endverbatim
- @note Icon data is in BGRA format. An alpha channel value of 255 means
- "fully opaque", and a value of 0 means "fully transparent".
-
-
- @def UNITY_RPC_GET_BINARY_HANDLERS
- @brief Ask the guest to return filetypes (extensions) and URL protocols
- supported by the guest.
- @todo Move this into a GHI-specific header.
- @code
- UNITY_RPC_GET_BINARY_HANDLERS
- @endcode
- @sa ghiGetBinaryHandlers.x for format of data returned.
-
-
- @def UNITY_RPC_OPEN_LAUNCHMENU
- @brief Get the start menu sub-tree for a given item
- @todo Move this into a GHI-specific header.
- @code
- UNITY_RPC_OPEN_LAUNCHMENU root [flags]
- @endcode
- @param[in] root Name of sub-tree, or "" for root of start menu.
- @param[in] flags @ref UNITY_START_MENU_FLAG_USE_PROGRAMS_FOLDER_AS_ROOT
- @return
-@verbatim
-retval ::= count handle
-
-count ::= ? Number of items in the sub-tree. ?
-handle ::= ? Opaque 32-bit integer used with subsequent calls to UNITY_RPC_GET_LAUNCHMENU_ITEM. ?
-@endverbatim
-
-
- @def UNITY_RPC_GET_LAUNCHMENU_ITEM
- @brief Get the nth item in the menu sub-tree.
- @todo Move this into a GHI-specific header.
- @code
- UNITY_RPC_GET_LAUNCHMENU_ITEM handle index
- @endcode
- @param[in] handle Handle returned by @ref UNITY_RPC_OPEN_LAUNCHMENU.
- @param[in] index index of the item to retrieve (zero-indexed).
- @return
-@verbatim
-retval ::= name '\0' flags '\0' shellPath '\0' localName
-
-name ::= ? Canonical item name used as a unique ID. ?
-flags ::= 0 | 1 (* 0 = leaf node, 1 = directory *)
-shellPath ::= ? Opaque executable path sent to UNITY_RPC_SHELL_OPEN. ?
-localName ::= ? Localized item name displayed by UI. ?
-@endverbatim
- @sa UNITY_RPC_SHELL_OPEN
-
-
- @def UNITY_RPC_CLOSE_LAUNCHMENU
- @brief Close the sub-menu, releasing all associated resources.
- @todo Move this into a GHI-specific header.
- @code
- UNITY_RPC_CLOSE_LAUNCHMENU handle
- @endcode
- @param[in] handle Handle returned by @ref UNITY_RPC_OPEN_LAUNCHMENU.
-
-
- @def UNITY_RPC_WINDOW_SETTOP
- @brief Raise a group of windows to the top of the window stacking order.
- @code
- UNITY_RPC_WINDOW_SETTOP UnityWindowId{ UnityWindowId}
- @endcode
- @param[in] UnityWindowId{ UnityWindowId} group of windows to raise
- @note Order of windows is bottom to top.
- @note Only @ref UNITY_MAX_SETTOP_WINDOW_COUNT windows can be specified.
-
-
- @def UNITY_RPC_WINDOW_CLOSE
- @brief Close the specified window.
- @code
- UNITY_RPC_WINDOW_CLOSE UnityWindowId
- @endcode
- @param[in] UnityWindowId window to close
-
-
- @def UNITY_RPC_GET_WINDOW_CONTENTS
- @brief Retreive pixel contents of the Window.
- @code
- UNITY_RPC_GET_WINDOW_CONTENTS UnityWindowId
- @endcode
- @param[in] UnityWindowId UnityWindowId of window to get contents from
- @return PNG image containing the window content.
-
-
- @def UNITY_RPC_GET_ICON_DATA
- @brief Return icon data for a specific window.
- @code
- UNITY_RPC_GET_ICON_DATA UnityWindowId type size dataOffset dataLength
- @endcode
- @param[in] UnityWindowId window to get icon data for
- @param[in] type UNITY_ICON_TYPE_MAIN
- @param[in] size size of icon e.g., 16, 32, 48
- @param[in] dataOffset offset into icon data client desires
- @param[in] dataLength number of bytes starting at dataOffset to return
- @return PNG image containing the icon data.
-
-
- @def UNITY_RPC_EXIT
- @brief Cease enumerating windows and leave Unity mode.
- @code
- UNITY_RPC_EXIT
- @endcode
- @note On success, the guest will send a @ref UNITY_RPC_UNITY_ACTIVE
- with an argument of 0 to indicate it has exited Unity mode.
-
-
- @def UNITY_RPC_GET_UPDATE_FULL
- @brief Equivalent to @ref UNITY_RPC_GET_UPDATE with no argument.
- @code
- UNITY_RPC_GET_UPDATE_FULL
- @endcode
- @return See @ref UnityGetUpdateReturn.
-
-
- @def UNITY_RPC_GET_UPDATE_INCREMENTAL
- @brief Equivalent to @ref UNITY_RPC_GET_UPDATE with an "incremental" argument.
- @code
- UNITY_RPC_GET_UPDATE_INCREMENTAL
- @endcode
- @return See @ref UnityGetUpdateReturn.
-
-
- @def UNITY_RPC_SHELL_OPEN
- @brief Open the application corresponding to the passed in URI or
- regular path.
- @todo Move this into a GHI-specific header.
- @code
- UNITY_RPC_SHELL_OPEN
- @endcode
- @param[in] path URI or path of executable to open
- @note The URI is opaque to the caller, the caller supplies this URI
- to the host with the expecation that it will be able to
- understand the format when this RPC is invoked.
-
-
- @def UNITY_RPC_SHOW_TASKBAR
- @brief Show or hide the guest taskbar.
- @code
- UNITY_RPC_SHOW_TASKBAR flag
- @endcode
- @param[in] flag 0 to hide the taskbar, or 1 to show the taskbar.
-
-
- @def UNITY_RPC_WINDOW_MOVE_RESIZE
- @brief Change the geometry of the specified window.
- @code
- UNITY_RPC_WINDOW_MOVE_RESIZE UnityWindowId x y width height
- @endcode
- @param[in] UnityWindowId UnityWindowId of window to modify
- @param[in] x x coordinate of desired window origin
- @param[in] y y coordinate of desired window origin
- @param[in] width desired width
- @param[in] height desired height
- @note Window origin refers to the upper left (north west) corner.
- @note It is possible that the result will not be as requested due
- to the layout policy of the guest desktop or window manager.
- @return The new window location, dimensions.
-@verbatim
-retval ::= newX newY newWidth newHeight ;
-newX ::= ? post-op north west corner X coordinate ? ;
-newY ::= ? post-op north west corner Y coordinate ? ;
-newWidth ::= ? post-op window width ? ;
-newHeight ::= ? post-op window height ? ;
-@endverbatim
-
-
- @def UNITY_RPC_DESKTOP_WORK_AREA_SET
- @brief Specify the desktop work areas.
- @todo Add more detail about this RPC and why it matters.
- @code
- UNITY_RPC_DESKTOP_WORK_AREA_SET <work_areas>
- @endcode
- @param[in] <work_areas> list of work areas
- @verbatim
-<work_areas> := <count>{ ',' x y width height }
-<count> := number of work areas to follow, 0 or greater
-@endverbatim
-
-
- @def UNITY_RPC_WINDOW_SHOW
- @brief Make the specified window visible.
- @code
- UNITY_RPC_WINDOW_SHOW UnityWindowId
- @endcode
- @param[in] UnityWindowId UnityWindowId of window to show
-
-
- @def UNITY_RPC_WINDOW_HIDE
- @brief Hide the specified window.
- @code
- UNITY_RPC_WINDOW_HIDE UnityWindowId
- @endcode
- @param[in] UnityWindowId UnityWindowId of window to hide
-
-
- @def UNITY_RPC_WINDOW_MINIMIZE
- @brief Minimize the specified window.
- @code
- UNITY_RPC_WINDOW_MINIMIZE UnityWindowId
- @endcode
- @param[in] UnityWindowId UnityWindowId of window to minimize
-
-
- @def UNITY_RPC_WINDOW_UNMINIMIZE
- @brief Unminimizes a window to its pre-minimization state.
- @code
- UNITY_RPC_WINDOW_UNMINIMIZE UnityWindowId
- @endcode
- @param[in] UnityWindowId window to unminimize
- @note This RPC originated as UNITY_RPC_WINDOW_RESTORE. The actual
- GuestRpc command remains as "unity.window.restore" to maintain
- backwards compatibility.
-
-
- @def UNITY_RPC_WINDOW_MAXIMIZE
- @brief Maximize the specified window.
- @code
- UNITY_RPC_WINDOW_MAXIMIZE UnityWindowId
- @endcode
- @param[in] UnityWindowId UnityWindowId of window to maximize
-
-
- @def UNITY_RPC_WINDOW_UNMAXIMIZE
- @brief Unmaximize the specified window.
- @code
- UNITY_RPC_WINDOW_UNMAXIMIZE UnityWindowId
- @endcode
- @param[in] UnityWindowId UnityWindowId of window to unmaximize
-
-
- @def UNITY_RPC_DESKTOP_CONFIG_SET
- @brief Send desktop (virtual workspaces) configuration.
- @code
- UNITY_RPC_DESKTOP_CONFIG_SET configuration
- @endcode
- @param[in] configuration <cell> {<cell>} <current>
- @verbatim
-<cell> := '{'row,col'}'
-<current> := currently active cell
-@endverbatim
-The RPC takes the form of a set of row, column pairs, each enclosed by
-braces, and an integer. The number of rows and columns can be deduced
-by looking for the max row and column value specified in these pairs.
-The integer that follows the list of pairs defines the currently active
-desktop, as an offset (starting at 0) of the pair list.\n\n
-For example: <tt>{1,1} {1,2} {2,1} {2,2} 1</tt> specifies a 2 x 2 virtual
-desktop where the upper right <tt>{1,2}</tt> is the currently active desktop.
-
-
- @def UNITY_RPC_DESKTOP_ACTIVE_SET
- @brief Change the active desktop to the value specified.
- @code
- UNITY_RPC_DESKTOP_ACTIVE_SET offset
- @endcode
- @param[in] offset Offset into desktop configuration, as defined by @ref UNITY_RPC_DESKTOP_CONFIG_SET, 0 or greater
-
-
- @def UNITY_RPC_WINDOW_DESKTOP_SET
- @brief Change the desktop of the specified window.
- @code
- UNITY_RPC_WINDOW_DESKTOP_SET UnityWindowId offset
- @endcode
- @param[in] UnityWindowId UnityWindowId of window to move
- @param[in] offset Offset into desktop configuration, as defined by
- @ref UNITY_RPC_DESKTOP_CONFIG_SET, 0 or greater.
-
- @def UNITY_RPC_SET_OPTIONS
- @brief Set optional behaviour for unity mode in the guest.
- @code
- UNITY_RPC_SET_OPTIONS
- @endcode
- @param[in] XDR encoded options mask.
- @note This must be called before entering Unity mode - setting the options
- after Unity mode has begun will result in undefined behaviour.
-
- @def UNITY_RPC_WINDOW_STICK
- @brief "Stick" a window to the screen.
- @code
- UNITY_RPC_WINDOW_STICK UnityWindowId
- @endcode
- @param[in] UnityWindowId UnityWindowId of window to stick.
-
- @def UNITY_RPC_WINDOW_UNSTICK
- @brief "Unstick" a window from the screen.
- @code
- UNITY_RPC_WINDOW_UNSTICK UnityWindowId
- @endcode
- @param[in] UnityWindowId UnityWindowId of window to unstick.
-
- @def UNITY_RPC_CONFIRM_OPERATION
- @brief Confirm (or deny) that a previously requested operation should now be performed.
- @code
- UNITY_RPC_CONFIRM_OPERATION XDR_REP
- @endcode
- @param[in] XDR_REP XDR Encoded (see unity.x) representation of arguments.
-
- @def UNITY_RPC_SEND_MOUSE_WHEEL
- @brief Send mouse wheel events to the window under the mouse.
- @code
- UNITY_RPC_SEND_MOUSE_WHEEL horizontal deltaX deltaY deltaZ modifierFlags
- @endcode
- @param[in] horizontal 0 to send vertical mouse wheel event, 1 for horizontal
- @param[in] deltaX the horizontal distance the wheel is rotated
- @param[in] deltaY the vertial distance the wheel is rotated
- @param[in] deltaZ the distance the wheel is rotated in the Z axis
- @param[in] modifierFlags modifier flags pressed during the event
-
- @def UNITY_RPC_WINDOW_CONTENTS_REQUEST
- @brief Request the asynchronous delivery of window contents.
- @code
- UNITY_RPC_WINDOW_CONTENTS_REQUEST XDR_REP
- @endcode
- @param[in] XDR_REP XDR Encoded (see unity.x) representation of arguments.
-
- @}
-*/
-
-
-/**
- @defgroup UnityRpcGH Unity RPCs: Guest-to-Host
- @{
-
- @def UNITY_RPC_PUSH_UPDATE_CMD
- @brief Send a round of Unity Window Tracker updates to the host.
- @todo doucment update format in unityWindowTracker.c
- @code
- UNITY_RPC_PUSH_UPDATE_CMD commands
- @endcode
- @param[in] A double-NUL-terminated string containing NUL-delimited update commands.
- @note Updates are followed in the command string by Z-order information,
- and active desktop information. The update format is documented in
- @ref unityWindowTracker.c
-
-
- @def UNITY_RPC_VMX_SHOW_TASKBAR
- @brief Ask the host to send its "show taskbar" setting.
- @code
- UNITY_RPC_VMX_SHOW_TASKBAR
- @endcode
-
-
- @def UNITY_RPC_UNITY_CAP
- @brief Tell the host if the guest is capable of supporting Unity or not.
- @code
- UNITY_RPC_UNITY_CAP flag
- @endcode
- @param[in] flag If 1, guest supports Unity. If 0, it does not
-
- @def UNITY_RPC_SHOW_TASKBAR_CAP
- @brief Tells the host if the guest is capable of showing and hiding the
- taskbar.
- @code
- UNITY_RPC_SHOW_TASKBAR_CAP flag
- @endcode
- @param[in] flag If 1, taskbar visibility can be controlled. If 0, it cannot
-
- @def GHI_RPC_LAUNCHMENU_CHANGE
- @brief Inform the host that one or more launch menu items have changed.
- @todo Move this define to a GHI-specific header.
- @code
- GHI_RPC_LAUNCHMENU_CHANGE
- @endcode
-
-
- @def GHI_RPC_PROTOCOL_HANDLER_INFO
- @brief This command sends the list of protocol handlers to the host.
- @todo Move this define to a GHI-specific header.
- @code
- GHI_RPC_PROTOCOL_HANDLER_INFO
- @endcode
- @param data XDR data containing protocol handler info.
- @sa GHIPlatformGetProtocolHandlers for platform-specific list of handled protocols.
- @sa ghiProtocolHandler.x for XDR data format.
-
-
- @def UNITY_RPC_UNITY_ACTIVE
- @brief Tell host we are entering or leaving Unity mode.
- @code
- UNITY_RPC_UNITY_ACTIVE flag
- @endcode
- @param[in] flag If 1, Unity is active. If 0, Unity is not active
-
- @def UNITY_RPC_REQUEST_OPERATION
- @brief Request that the host should allow the guest to perform an operation.
- @code
- UNITY_RPC_REQUEST_OPERATION XDR_REP
- @endcode
- @param[in] XDR_REP XDR Encoded (see unity.x) representation of arguments.
-
- @def UNITY_RPC_ACK_OPERATION
- @brief Acknowledge that a previously confirmed operations has been performed.
- @code
- UNITY_RPC_ACK_OPERATION XDR_REP
- @endcode
- @param[in] XDR_REP XDR Encoded (see unity.x) representation of arguments.
-
- @def UNITY_RPC_WINDOW_CONTENTS_START
- @brief The start of data for the pixel contents of the window.
- @code
- UNITY_RPC_WINDOW_CONTENTS_START XDR_REP
- @endcode
- @param[in] XDR_REP XDR Encoded (see unity.x) representation of arguments.
-
- @def UNITY_RPC_WINDOW_CONTENTS_CHUNK
- @brief One (<64KB) chunk of Pixel Data for a previously started window.
- @code
- UNITY_RPC_WINDOW_CONTENTS_CHUNK XDR_REP
- @endcode
- @param[in] XDR_REP XDR Encoded (see unity.x) representation of arguments.
-
- @def UNITY_RPC_WINDOW_CONTENTS_END
- @brief The end of data for the pixel contents of the window.
- @code
- UNITY_RPC_WINDOW_CONTENTS_END XDR_REP
- @endcode
- @param[in] XDR_REP XDR Encoded (see unity.x) representation of arguments.
-
- @}
-*/
-
-
-/**
- * @page UnityGetUpdateReturn UNITY_RPC_GET_UPDATE RPC Return Value
- *
- * The return value of this RPC is a mapping of @ref UnityWindowTracker updates
- * to GuestRpc-safe text strings. (Think of this simply as a poor-man's
- * marshalling scheme between the UnityWindowTrackers running in the Unity
- * Agent and Server (presently the VMware Tools and VMX/MKS, respectively).
- *
- * @sa
- * @li UNITY_RPC_GET_UPDATE
- * @li UNITY_RPC_GET_UPDATE_FULL
- * @li UNITY_RPC_GET_UPDATE_INCREMENTAL
- *
- * @section URGUReturnFormat Return value format
- *
- * The reply to the RPC is a double-null-terminated list of null-terminated
- * strings.
- *
- * Each string in the list has one of the following formats:
- *
- * @li <tt>"add" UnityWindowId arguments</tt> @par
- * A window identified by @a UnityWindowId has just been created.
- * The @a arguments are optional, and are not provided by all Tools.
- * Arguments are space-separated key=value pairs, with the following
- * keys: windowPath, execPath. The values are the same as what is
- * returned by the @ref UNITY_RPC_GET_WINDOW_PATH RPC.
- *
- * @li <tt>"remove" UnityWindowId</tt> @par
- * The window identified by @a UnityWindowId has been removed. Get rid
- * of it.
- *
- * @li <tt>"move" UnityWindowId x1 y1 x2 y2</tt> @par
- * The window identified by @a UnityWindowId has moved or resized such
- * that its top left corner rests at <tt>(x1, y1)</tt> and its bottom
- * right at <tt>(x2, y2)</tt>.
- *
- * @li <tt>"region" UnityWindowId numrects</tt> @par
- * The window identified by @a UnityWindowId has a not-rectangular window
- * region (e.g. the curved corner windows in Windows XP). Immediately,
- * after this message are @c numrects messages with the following (@ref
- * rect) format.
- * @par
- * The actual window region is the union of all the rectangles in the list.
- * A value of 0 for @c numrects indicates that the window region should
- * be ignored (i.e. the window region is identical to the bounds of
- * the window).
- *
- * @li <tt>"rect" x1 y1 x2 y2</tt> @par
- * @anchor rect Defines a rectangle in the coordinate system of the window
- * for this region (not the coordinate system of the desktop!!)
- *
- * @li <tt>"title" UnityWindowId title</tt> @par
- * A window identified by @a UnityWindowId has just changed its to @a title.
- *
- * @li <tt>"zorder" numWindows UnityWindowId {UnityWindowId}</tt> @par
- * Resets the Z order of @a numWindows Unity windows in top-to-bottom order.
- *
- * @li <tt>"attr" UnityWindowId UnityWindowAttribute enabled</tt> @par
- * <tt>enabled ::= "0" | "1"</tt>\n The window identified by @a
- * UnityWindowId has an attribute enabled/disabled.
- *
- * @li <tt>"type" UnityWindowId UnityWindowType</tt> @par
- * The window identified by @a UnityWindowId is of a certain type
- *
- * @li <tt>"icon" UnityWindowId UnityIconType</tt> @par
- * The window identified by @a UnityWindowId has changed its icon type
- * to @a UnityIconType.
- *
- * @li <tt>"desktop" UnityWindowId UnityDesktopId</tt> @par
- * The window identified by @a UnityWindowId has been moved to the desktop
- * identified by @a UnityDesktopId.
- *
- * @li <tt>"activedesktop" UnityDesktopId</tt> @par
- * The desktop identified by @a UnityDesktopId has become active.
- *
- * @subsection ""
- * @sa UnityWindowId, UnityDesktopId, UnityWindowType, UnityIconType
- */
-
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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.
- *
- *********************************************************/
-
-#ifndef _UNITYEVENTS_H_
-#define _UNITYEVENTS_H_
-
-/**
- * @file unityevents.h
- *
- * Public interface for the "unity" plugin. This plugin (via libunity) exposes
- * an event published when unity is entered and exited.
- *
- * @addtogroup vmtools_plugins
- * @{
- */
-
-/**
- * Signal sent when unity is entered or exited.
- *
- * @param[in] src The source object.
- * @param[in] enter If TRUE, unity has been entered. If FALSE, it
- * has been exited.
- */
-#define UNITY_SIG_ENTER_LEAVE_UNITY "unity_enter_leave_unity"
-
-/** @} */
-
-#endif /* _UNITYEVENTS_H_ */
-
+++ /dev/null
-################################################################################
-### Copyright 2008 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
-################################################################################
-
-noinst_LTLIBRARIES = libRaster.la
-
-libRaster_la_SOURCES =
-libRaster_la_SOURCES += rasterConv.c
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * rasterConv.c --
- *
- * Pixel conversion routines
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "vmware.h"
-#include "rasterConv.h"
-
-#define CONVERT_LONG_TO_SHORT(pix, redMask, greenMask, blueMask, \
- redShift, greenShift, blueShift) \
- (((redMask) & ((pix) >> (redShift))) | \
- ((greenMask) & ((pix) >> (greenShift))) | \
- ((blueMask) & ((pix) >> (blueShift))))
-
-#define CONVERT_SHORT_TO_LONG(pix, redMask, greenMask, blueMask, \
- redShift1, redShift2, \
- greenShift1, greenShift2, \
- blueShift1, blueShift2) \
- ((REDMASK_32 & \
- (((((pix) & (redMask)) >> (redShift1)) | \
- (((pix) & (redMask)) >> (redShift2))) << 16)) | \
- (GREENMASK_32 & \
- (((((pix) & (greenMask)) >> (greenShift1)) | \
- (((pix) & (greenMask)) >> (greenShift2))) << 8)) | \
- (BLUEMASK_32 & \
- ((((pix) & (blueMask)) << (blueShift1)) | \
- (((pix) & (blueMask)) >> (blueShift2)))))
-
-#define CONVERT_LONG_TO_8BGR(pix, redMask, greenMask, blueMask, \
- redShift, greenShift, blueShift) \
- (((redMask) & ((pix) >> (redShift))) | \
- ((greenMask) & ((pix) >> (greenShift))) | \
- ((blueMask) & ((pix) << (blueShift))))
-
-
-static const uint8 byte_masks_8bgr[9][3] = {
- /*0*/ {0,0,0},
- /*1*/ {0,0,0},
- /*2*/ {0,0,0},
- /*3*/ {REDMASK_BGR111, GREENMASK_BGR111, BLUEMASK_BGR111},
- /*4*/ {0,0,0},
- /*5*/ {0,0,0},
- /*6*/ {REDMASK_RGB222, GREENMASK_RGB222, BLUEMASK_RGB222},
- /*7*/ {0,0,0},
- /*8*/ {REDMASK_BGR233, GREENMASK_BGR233, BLUEMASK_BGR233}
-};
-
-#define REDMASK_8BPP(depth) (byte_masks_8bgr[depth][0])
-#define GREENMASK_8BPP(depth) (byte_masks_8bgr[depth][1])
-#define BLUEMASK_8BPP(depth) (byte_masks_8bgr[depth][2])
-
-
-/*
- * Local functions
- */
-
-static void RasterConvert15to16(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h);
-static void RasterConvertShortTo24(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask,
- uint32 blueMask,
- uint32 redShift1, uint32 redShift2,
- uint32 greenShift1, uint32 greenShift2,
- uint32 blueShift1, uint32 blueShift2);
-static void RasterConvertShortTo32(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask,
- uint32 blueMask,
- uint32 redShift1, uint32 redShift2,
- uint32 greenShift1, uint32 greenShift2,
- uint32 blueShift1, uint32 blueShift2);
-static void RasterConvert16to15(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h);
-static void RasterConvert24toShort(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask,
- uint32 blueMask,
- uint32 redShift, uint32 greenShift,
- uint32 blueShift);
-static void RasterConvert24to32(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h);
-static void RasterConvert32toShort(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask,
- uint32 blueMask,
- uint32 redShift, uint32 greenShift,
- uint32 blueShift);
-static void RasterConvert32to24(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h);
-static void RasterConvertIndextoShort(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- const uint32 *pixels,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask,
- uint32 blueMask,
- uint32 redShift, uint32 greenShift,
- uint32 blueShift);
-static void RasterConvertIndexto24(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- const uint32 *pixels,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h);
-static void RasterConvertIndexto32(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- const uint32 *pixels,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h);
-
-static void RasterConvert32to8(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask, uint32 blueMask,
- uint32 redShift, uint32 greenShift, uint32 blueShift);
-static void RasterConvert24to8(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask, uint32 blueMask,
- uint32 redShift, uint32 greenShift, uint32 blueShift);
-static void RasterConvert16to8(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask, uint32 blueMask,
- int redShift, int greenShift, int blueShift);
-static void RasterConvertIndexto8(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- const uint32 *pixels,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask, uint32 blueMask,
- uint32 redShift, uint32 greenShift, uint32 blueShift);
-static int RasterGetShiftFromMask(uint32 start, uint32 mask);
-static INLINE uint32 RasterShiftPixel(uint32 pixel, int shift);
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Raster_IsModeReasonable --
- *
- * Determine if a mode is something that Raster_Convert*
- * can deal with.
- *
- * Results:
- * TRUE if we like the mode.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-Bool
-Raster_IsModeReasonable(uint32 depth, uint32 bpp, Bool pseudocolor)
-{
- return (pseudocolor && bpp == 8) || (!pseudocolor &&
- ((bpp == 16 && (depth == 15 ||
- depth == 16)) ||
- (bpp == 24 && depth == 24) ||
- (bpp == 32 && depth == 24)));
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Raster_GetBPPDepth --
- *
- * Converts separate depth and bpp values into one "bppdepth."
- * See comment above Raster_ConvertPixels().
- *
- * Results:
- * The bppdepth.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-int
-Raster_GetBPPDepth(uint32 depth, uint32 bpp)
-{
- if (depth == 24 && bpp == 32) {
- return 32;
- } else {
- return depth;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Raster_ConvertPixels --
- *
- * Convert pixels from one depth to another, while copying from
- * source to destination.
- *
- * bppdepth is a unique number specifying the bpp/color-depth,
- * like so:
- *
- * bpp depth bppdepth
- * -----------------------
- * 8 3 3
- * 8 6 6
- * 8 8 8
- * 16 15 15
- * 16 16 16
- * 24 24 24
- * 32 24 32 * This is the only one that differs from depth
- *
- * Results:
- * None
- *
- * Side effects:
- * If converting from a lower true-color depth to 32-bpp, fills the
- * alpha values of the destination rectangle to 0xFF.
- *
- *----------------------------------------------------------------------
- */
-
-void
-Raster_ConvertPixels(uint8 *tof, int32 line_increment, int bppdepth,
- const uint8 *src, int32 src_increment, int src_bppdepth,
- Bool pseudoColor, const uint32 *pixels,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h)
-{
- int redShift, greenShift, blueShift;
-
- if (pseudoColor) {
- if (src_bppdepth > 8) {
- Warning("Raster convert pixels invalid depth for pseudo color %d\n",
- src_bppdepth);
- NOT_IMPLEMENTED();
- return;
- }
-
- switch (bppdepth) {
- case 3: case 6: case 8:
- redShift = RasterGetShiftFromMask(24, REDMASK_8BPP(bppdepth));
- greenShift = RasterGetShiftFromMask(16, GREENMASK_8BPP(bppdepth));
- blueShift = RasterGetShiftFromMask(8, BLUEMASK_8BPP(bppdepth));
- ASSERT(redShift >= 0 && greenShift >= 0 && blueShift >= 0);
-
- RasterConvertIndexto8(tof, line_increment, src, src_increment,
- pixels, src_x, src_y, x, y, w, h,
- REDMASK_8BPP(bppdepth),
- GREENMASK_8BPP(bppdepth),
- BLUEMASK_8BPP(bppdepth),
- redShift, greenShift, blueShift);
- break;
-
- case 15:
- RasterConvertIndextoShort(tof, line_increment, src, src_increment,
- pixels, src_x, src_y, x, y, w, h,
- REDMASK_15, GREENMASK_15, BLUEMASK_15,
- 9, 6, 3);
- break;
-
- case 16:
- RasterConvertIndextoShort(tof, line_increment, src, src_increment,
- pixels, src_x, src_y, x, y, w, h,
- REDMASK_16, GREENMASK_16, BLUEMASK_16,
- 8, 5, 3);
- break;
-
- case 24:
- RasterConvertIndexto24(tof, line_increment, src, src_increment,
- pixels, src_x, src_y, x, y, w, h);
- break;
-
- case 32:
- RasterConvertIndexto32(tof, line_increment, src, src_increment,
- pixels, src_x, src_y, x, y, w, h);
- break;
-
- default:
- Warning("Raster convert pixels invalid depth %d\n", bppdepth);
- NOT_IMPLEMENTED();
- break;
- }
- return;
- }
-
- switch (src_bppdepth) {
- case 15:
- switch (bppdepth) {
- case 3: case 6: case 8:
- redShift = RasterGetShiftFromMask(15, REDMASK_8BPP(bppdepth));
- greenShift = RasterGetShiftFromMask(10, GREENMASK_8BPP(bppdepth));
- blueShift = RasterGetShiftFromMask(5, BLUEMASK_8BPP(bppdepth));
-
- RasterConvert16to8(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h,
- REDMASK_8BPP(bppdepth),
- GREENMASK_8BPP(bppdepth),
- BLUEMASK_8BPP(bppdepth),
- redShift, greenShift, blueShift);
- break;
-
- case 15:
- Warning("Raster convert called when no conversion needed\n");
- NOT_IMPLEMENTED();
- break;
-
- case 16:
- RasterConvert15to16(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h);
- break;
-
- case 24:
- RasterConvertShortTo24(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h,
- REDMASK_15, GREENMASK_15, BLUEMASK_15,
- 7, 12, 2, 7, 3, 2);
- break;
-
- case 32:
- RasterConvertShortTo32(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h,
- REDMASK_15, GREENMASK_15, BLUEMASK_15,
- 7, 12, 2, 7, 3, 2);
- break;
-
- default:
- Warning("Raster convert pixels invalid depth %d\n", bppdepth);
- NOT_IMPLEMENTED();
- break;
- }
- break;
-
- case 16:
- switch (bppdepth) {
- case 3: case 6: case 8:
- redShift = RasterGetShiftFromMask(16, REDMASK_8BPP(bppdepth));
- greenShift = RasterGetShiftFromMask(11, GREENMASK_8BPP(bppdepth));
- blueShift = RasterGetShiftFromMask(5, BLUEMASK_8BPP(bppdepth));
-
- RasterConvert16to8(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h,
- REDMASK_8BPP(bppdepth),
- GREENMASK_8BPP(bppdepth),
- BLUEMASK_8BPP(bppdepth),
- redShift, greenShift, blueShift);
- break;
-
- case 15:
- RasterConvert16to15(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h);
- break;
-
- case 16:
- Warning("Raster convert called when no conversion needed\n");
- NOT_IMPLEMENTED();
- break;
-
- case 24:
- RasterConvertShortTo24(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h,
- REDMASK_16, GREENMASK_16, BLUEMASK_16,
- 8, 13, 3, 9, 3, 2);
- break;
-
- case 32:
- RasterConvertShortTo32(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h,
- REDMASK_16, GREENMASK_16, BLUEMASK_16,
- 8, 13, 3, 9, 3, 2);
- break;
-
- default:
- Warning("Raster convert pixels invalid depth %d\n", bppdepth);
- NOT_IMPLEMENTED();
- break;
- }
- break;
-
- case 24:
- switch (bppdepth) {
- case 3: case 6: case 8:
- redShift = RasterGetShiftFromMask(8, REDMASK_8BPP(bppdepth));
- greenShift = RasterGetShiftFromMask(8, GREENMASK_8BPP(bppdepth));
- blueShift = RasterGetShiftFromMask(8, BLUEMASK_8BPP(bppdepth));
- ASSERT(redShift >= 0 && greenShift >= 0 && blueShift >= 0);
-
- RasterConvert24to8(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h,
- REDMASK_8BPP(bppdepth),
- GREENMASK_8BPP(bppdepth),
- BLUEMASK_8BPP(bppdepth),
- redShift, greenShift, blueShift);
- break;
-
- case 15:
- RasterConvert24toShort(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h,
- REDMASK_15, GREENMASK_15, BLUEMASK_15,
- 7, 2, 3);
- break;
-
- case 16:
- RasterConvert24toShort(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h,
- REDMASK_16, GREENMASK_16, BLUEMASK_16,
- 8, 3, 3);
- break;
-
- case 24:
- Warning("Raster convert called when no conversion needed\n");
- NOT_IMPLEMENTED();
- break;
-
- case 32:
- RasterConvert24to32(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h);
- break;
-
- default:
- Warning("Raster convert pixels invalid depth %d\n", bppdepth);
- NOT_IMPLEMENTED();
- break;
- }
- break;
-
- case 32:
- switch (bppdepth) {
- case 3: case 6: case 8:
- redShift = RasterGetShiftFromMask(24, REDMASK_8BPP(bppdepth));
- greenShift = RasterGetShiftFromMask(16, GREENMASK_8BPP(bppdepth));
- blueShift = RasterGetShiftFromMask(8, BLUEMASK_8BPP(bppdepth));
- ASSERT(redShift >= 0 && greenShift >= 0 && blueShift >= 0);
-
- RasterConvert32to8(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h,
- REDMASK_8BPP(bppdepth),
- GREENMASK_8BPP(bppdepth),
- BLUEMASK_8BPP(bppdepth),
- redShift, greenShift, blueShift);
- break;
-
- case 15:
- RasterConvert32toShort(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h,
- REDMASK_15, GREENMASK_15, BLUEMASK_15,
- 9, 6, 3);
- break;
-
- case 16:
- RasterConvert32toShort(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h,
- REDMASK_16, GREENMASK_16, BLUEMASK_16,
- 8, 5, 3);
- break;
-
- case 24:
- RasterConvert32to24(tof, line_increment, src, src_increment,
- src_x, src_y, x, y, w, h);
- break;
-
- case 32:
- Warning("Raster convert called when no conversion needed\n");
- NOT_IMPLEMENTED();
- break;
-
- default:
- Warning("Raster convert pixels invalid depth %d\n", bppdepth);
- NOT_IMPLEMENTED();
- break;
- }
- break;
-
- default:
- Warning("Raster convert pixels invalid source depth %d\n", src_bppdepth);
- NOT_IMPLEMENTED_BUG(10982);
- break;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Raster_ConvertOnePixel --
- *
- * Convert the given pixel from its current depth to the specified
- * depth.
- *
- * Results:
- * The converted pixel
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-uint32
-Raster_ConvertOnePixel(uint32 pix, int src_bppdepth, int bppdepth,
- Bool pseudoColor, const uint32 *pixels)
-{
- if (pseudoColor) {
- if (src_bppdepth != 8) {
- Warning("Raster convert pixels invalid depth for pseudo color %d\n",
- src_bppdepth);
- NOT_IMPLEMENTED();
- return 0;
- }
- pix = pixels[pix];
- src_bppdepth = 32;
- }
-
- switch (src_bppdepth) {
- case 15:
- switch (bppdepth) {
- case 3: case 6: case 8:
- return CONVERT_LONG_TO_8BGR(pix, REDMASK_8BPP(bppdepth),
- GREENMASK_8BPP(bppdepth),
- BLUEMASK_8BPP(bppdepth), 12, 4, 3);
-
- case 15:
- return pix;
-
- case 16:
- return ((pix & (REDMASK_15 | GREENMASK_15)) << 1) |
- ((pix & GREEN_HIBIT_15) >> GREEN_HILOSHIFT_15) |
- (pix & BLUEMASK_16);
-
- case 24:
- case 32:
- return CONVERT_SHORT_TO_LONG(pix, REDMASK_15, GREENMASK_15,
- BLUEMASK_15, 7, 12, 2, 7, 3, 2);
-
- default:
- Warning("Raster convert one pixel invalid depth %d\n", bppdepth);
- NOT_IMPLEMENTED();
- return 0;
- }
-
- case 16:
- switch (bppdepth) {
- case 3: case 6: case 8:
- return CONVERT_LONG_TO_8BGR(pix, REDMASK_8BPP(bppdepth),
- GREENMASK_8BPP(bppdepth),
- BLUEMASK_8BPP(bppdepth), 13, 5, 3);
-
- case 15:
- return ((pix >> 1) & (REDMASK_15 | GREENMASK_15)) |
- (pix & BLUEMASK_15);
-
- case 16:
- return pix;
-
- case 24:
- case 32:
- return CONVERT_SHORT_TO_LONG(pix, REDMASK_16, GREENMASK_16,
- BLUEMASK_16, 8, 13, 3, 9, 3, 2);
-
- default:
- Warning("Raster convert one pixel invalid depth %d\n", bppdepth);
- NOT_IMPLEMENTED();
- return 0;
- }
-
- case 24:
- case 32:
- switch (bppdepth) {
- case 3: case 6: case 8:
- return CONVERT_LONG_TO_8BGR(pix, REDMASK_8BPP(bppdepth),
- GREENMASK_8BPP(bppdepth),
- BLUEMASK_8BPP(bppdepth), 21, 10, 0);
-
- case 15:
- return CONVERT_LONG_TO_SHORT(pix, REDMASK_15, GREENMASK_15,
- BLUEMASK_15, 9, 6, 3);
-
- case 16:
- return CONVERT_LONG_TO_SHORT(pix, REDMASK_16, GREENMASK_16,
- BLUEMASK_16, 8, 5, 3);
-
- case 24:
- case 32:
- return pix;
-
- default:
- Warning("Raster convert one pixel invalid depth %d\n", bppdepth);
- NOT_IMPLEMENTED();
- return 0;
- }
-
- default:
- Warning("Raster convert one pixel invalid source depth %d\n",
- src_bppdepth);
- NOT_IMPLEMENTED();
- return 0;
- }
-
- return pix;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Raster_ConversionParameters --
- *
- * Get component masks that the conversion routines use for the
- * supported depths
- *
- * Results:
- * Returns FALSE if depth not supported
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-Bool
-Raster_ConversionParameters(int bppdepth, // IN
- uint32 *redMask, // OUT
- uint32 *greenMask, // OUT
- uint32 *blueMask) // OUT
-{
- switch (bppdepth) {
- case 15:
- *redMask = REDMASK_15;
- *greenMask = GREENMASK_15;
- *blueMask = BLUEMASK_15;
- break;
-
- case 16:
- *redMask = REDMASK_16;
- *greenMask = GREENMASK_16;
- *blueMask = BLUEMASK_16;
- break;
-
- case 24:
- *redMask = REDMASK_24;
- *greenMask = GREENMASK_24;
- *blueMask = BLUEMASK_24;
- break;
-
- case 32:
- *redMask = REDMASK_32;
- *greenMask = GREENMASK_32;
- *blueMask = BLUEMASK_32;
- break;
-
- default:
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvert15to16 --
- *
- * Convert pixels from depth 15 to depth 16, while copying from
- * source to destination.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvert15to16(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h)
-{
- const uint16 *srcptr;
- uint16 *dstptr;
- int i, j;
-
- src_increment >>= 1;
- srcptr = (uint16 *)src;
- srcptr += (src_y * src_increment) + src_x;
-
- line_increment >>= 1;
- dstptr = (uint16 *)tof;
- dstptr += (y * line_increment) + x;
-
- for (i=0; i<h; i++) {
- for (j=0; j<w; j++) {
- uint32 pix = srcptr[j];
- dstptr[j] = ((pix & (REDMASK_15 | GREENMASK_15)) << 1) |
- ((pix & GREEN_HIBIT_15) >> GREEN_HILOSHIFT_15) |
- (pix & BLUEMASK_16);
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvertShortTo24 --
- *
- * Convert pixels from depth 15 or 16 to depth 24, while copying
- * from source to destination.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvertShortTo24(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask, uint32 blueMask,
- uint32 redShift1, uint32 redShift2,
- uint32 greenShift1, uint32 greenShift2,
- uint32 blueShift1, uint32 blueShift2)
-{
- const uint16 *srcptr;
- uint8 *dstptr;
- int i, j, k;
-
- src_increment >>= 1;
- srcptr = (uint16 *)src;
- srcptr += (src_y * src_increment) + src_x;
-
- dstptr = tof;
- dstptr += (y * line_increment) + (x * 3);
-
- for (i=0; i<h; i++) {
- for (j=0, k=0; j<w; j++) {
- uint32 pix = srcptr[j];
- dstptr[k++] = ((pix & blueMask) << blueShift1) |
- ((pix & blueMask) >> blueShift2);
- dstptr[k++] = ((pix & greenMask) >> greenShift1) |
- ((pix & greenMask) >> greenShift2);
- dstptr[k++] = ((pix & redMask) >> redShift1) |
- ((pix & redMask) >> redShift2);
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvertShortTo32 --
- *
- * Convert pixels from depth 15 or 16 to depth 32, while copying
- * from source to destination.
- *
- * Results:
- * None
- *
- * Side effects:
- * Fills the alpha values of the destination rectangle to 0xFF.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvertShortTo32(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask, uint32 blueMask,
- uint32 redShift1, uint32 redShift2,
- uint32 greenShift1, uint32 greenShift2,
- uint32 blueShift1, uint32 blueShift2)
-{
- const uint16 *srcptr;
- uint32 *dstptr;
- int i, j;
-
- src_increment >>= 1;
- srcptr = (uint16 *)src;
- srcptr += (src_y * src_increment) + src_x;
-
- line_increment >>= 2;
- dstptr = (uint32 *)tof;
- dstptr += (y * line_increment) + x;
-
- for (i=0; i<h; i++) {
- for (j=0; j<w; j++) {
- uint32 pix = srcptr[j];
- dstptr[j] = (0xFF << 24) |
- (REDMASK_32 &
- ((((pix & redMask) >> redShift1) |
- ((pix & redMask) >> redShift2)) << 16)) |
- (GREENMASK_32 &
- ((((pix & greenMask) >> greenShift1) |
- ((pix & greenMask) >> greenShift2)) << 8)) |
- (BLUEMASK_32 &
- (((pix & blueMask) << blueShift1) |
- ((pix & blueMask) >> blueShift2)));
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvert16to15 --
- *
- * Convert pixels from depth 16 to depth 15, while copying from
- * source to destination.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvert16to15(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h)
-{
- const uint16 *srcptr;
- uint16 *dstptr;
- int i, j;
-
- src_increment >>= 1;
- srcptr = (uint16 *)src;
- srcptr += (src_y * src_increment) + src_x;
-
- line_increment >>= 1;
- dstptr = (uint16 *)tof;
- dstptr += (y * line_increment) + x;
-
- for (i=0; i<h; i++) {
- for (j=0; j<w; j++) {
- uint32 pix = srcptr[j];
- dstptr[j] = ((pix >> 1) & (REDMASK_15 | GREENMASK_15)) |
- (pix & BLUEMASK_15);
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvert24toShort --
- *
- * Convert pixels from depth 24 to depth 15 or 16, while copying
- * from source to destination.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvert24toShort(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask, uint32 blueMask,
- uint32 redShift, uint32 greenShift, uint32 blueShift)
-{
- const uint8 *srcptr;
- uint16 *dstptr;
- int i, j, k;
-
- srcptr = src;
- srcptr += (src_y * src_increment) + (src_x * 3);
-
- line_increment >>= 1;
- dstptr = (uint16 *)tof;
- dstptr += (y * line_increment) + x;
-
- for (i=0; i<h; i++) {
- for (j=0, k=0; j<w; j++) {
- uint8 blue = srcptr[k++];
- uint8 green = srcptr[k++];
- uint8 red = srcptr[k++];
- dstptr[j] = ((red << redShift) & redMask) |
- ((green << greenShift) & greenMask) |
- ((blue >> blueShift) & blueMask);
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvert24to32 --
- *
- * Convert pixels from depth 24 to depth 32, while copying
- * from source to destination.
- *
- * Results:
- * None
- *
- * Side effects:
- * Fills the alpha values of the destination rectangle to 0xFF.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvert24to32(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h)
-{
- const uint8 *srcptr;
- uint32 *dstptr;
- int i, j, k;
-
- srcptr = src;
- srcptr += (src_y * src_increment) + (src_x * 3);
-
- line_increment >>= 2;
- dstptr = (uint32 *)tof;
- dstptr += (y * line_increment) + x;
-
- for (i=0; i<h; i++) {
- for (j=0, k=0; j<w; j++) {
- uint8 blue = srcptr[k++];
- uint8 green = srcptr[k++];
- uint8 red = srcptr[k++];
- dstptr[j] = (0xFF << 24) |
- ((red << 16) & REDMASK_32) |
- ((green << 8) & GREENMASK_32) |
- (blue & BLUEMASK_32);
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvert32toShort --
- *
- * Convert pixels from depth 32 to depth 15 or 16, while copying
- * from source to destination.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvert32toShort(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask, uint32 blueMask,
- uint32 redShift, uint32 greenShift, uint32 blueShift)
-{
- const uint32 *srcptr;
- uint16 *dstptr;
- int i, j;
-
- src_increment >>= 2;
- srcptr = (uint32 *)src;
- srcptr += (src_y * src_increment) + src_x;
-
- line_increment >>= 1;
- dstptr = (uint16 *)tof;
- dstptr += (y * line_increment) + x;
-
- for (i=0; i<h; i++) {
- for (j=0; j<w; j++) {
- uint32 pix = srcptr[j];
- dstptr[j] = (redMask & (pix >> redShift)) |
- (greenMask & (pix >> greenShift)) |
- (blueMask & (pix >> blueShift));
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvert32to24 --
- *
- * Convert pixels from depth 32 to depth 24, while copying
- * from source to destination.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvert32to24(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h)
-{
- const uint32 *srcptr;
- uint8 *dstptr;
- int i, j, k;
-
- src_increment >>= 2;
- srcptr = (uint32 *)src;
- srcptr += (src_y * src_increment) + src_x;
-
- dstptr = tof;
- dstptr += (y * line_increment) + (x * 3);
-
- for (i=0; i<h; i++) {
- for (j=0, k=0; j<w; j++) {
- uint32 pix = srcptr[j];
- dstptr[k++] = pix & BLUEMASK_32;
- dstptr[k++] = (pix & GREENMASK_32) >> 8;
- dstptr[k++] = (pix & REDMASK_32) >> 16;
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvertIndexto8 --
- *
- * Convert pixels from pseudo color values to depth 8 true color while
- * copying from source to destination.
- * BGR233: redShift: 21 greenShift: 10 blueShift: 0
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvertIndexto8(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment, const uint32 *pixels,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask, uint32 blueMask,
- uint32 redShift, uint32 greenShift, uint32 blueShift)
-{
- const uint8 *srcptr;
- uint8 *dstptr;
- int i, j;
-
- srcptr = src;
- srcptr += (src_y * src_increment) + src_x;
-
- dstptr = (uint8 *)tof;
- dstptr += (y * line_increment) + x;
-
- for (i=0; i<h; i++) {
- for (j=0; j<w; j++) {
- uint32 pix = pixels[srcptr[j]];
- dstptr[j] = (redMask & (pix >> redShift)) |
- (greenMask & (pix >> greenShift)) |
- (blueMask & (pix >> blueShift));
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvertIndextoShort --
- *
- * Convert pixels from pseudo color values to depth 15 or 16, while
- * copying from source to destination.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvertIndextoShort(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment, const uint32 *pixels,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask, uint32 blueMask,
- uint32 redShift, uint32 greenShift, uint32 blueShift)
-{
- const uint8 *srcptr;
- uint16 *dstptr;
- int i, j;
-
- srcptr = src;
- srcptr += (src_y * src_increment) + src_x;
-
- line_increment >>= 1;
- dstptr = (uint16 *)tof;
- dstptr += (y * line_increment) + x;
-
- for (i=0; i<h; i++) {
- for (j=0; j<w; j++) {
- uint32 pix = pixels[srcptr[j]];
- dstptr[j] = (redMask & (pix >> redShift)) |
- (greenMask & (pix >> greenShift)) |
- (blueMask & (pix >> blueShift));
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvertIndexto24 --
- *
- * Convert pixels from pseudo color values to depth 24, while copying
- * from source to destination.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvertIndexto24(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment, const uint32 *pixels,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h)
-{
- const uint8 *srcptr;
- uint8 *dstptr;
- int i, j, k;
-
- srcptr = src;
- srcptr += (src_y * src_increment) + src_x;
-
- dstptr = tof;
- dstptr += (y * line_increment) + (x * 3);
-
- for (i=0; i<h; i++) {
- for (j=0, k=0; j<w; j++) {
- uint32 pix = pixels[srcptr[j]];
- dstptr[k++] = pix & BLUEMASK_32;
- dstptr[k++] = (pix & GREENMASK_32) >> 8;
- dstptr[k++] = (pix & REDMASK_32) >> 16;
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvertIndexto32 --
- *
- * Convert pixels from pseudo color values to depth 32, while copying
- * from source to destination.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvertIndexto32(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment, const uint32 *pixels,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h)
-{
- const uint8 *srcptr;
- uint32 *dstptr;
- int i, j;
-
- srcptr = src;
- srcptr += (src_y * src_increment) + src_x;
-
- line_increment >>= 2;
- dstptr = (uint32 *)tof;
- dstptr += (y * line_increment) + x;
-
- for (i=0; i<h; i++) {
- for (j=0; j<w; j++) {
- uint32 pix = pixels[srcptr[j]];
- dstptr[j] = pix;
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvert32to8 --
- *
- * Convert pixels from depth 32 to depth 8, while copying
- * from source to destination.
- * BGR233: redShift: 21 greenShift: 10 blueShift: 0
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvert32to8(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask, uint32 blueMask,
- uint32 redShift, uint32 greenShift, uint32 blueShift)
-{
- const uint32 *srcptr;
- uint8 *dstptr;
- int i, j;
-
- src_increment >>= 2;
- srcptr = (uint32 *)src;
- srcptr += (src_y * src_increment) + src_x;
-
- dstptr = (uint8 *)tof;
- dstptr += (y * line_increment) + x;
-
- for (i=0; i<h; i++) {
- for (j=0; j<w; j++) {
- uint32 pix = srcptr[j];
- dstptr[j] = (redMask & (pix >> redShift)) |
- (greenMask & (pix >> greenShift)) |
- (blueMask & (pix >> blueShift));
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvert24to8 --
- *
- * Convert pixels from depth 24 to depth 8, while copying
- * from source to destination.
- * BGR233: redShift: 5 greenShift: 2 blueShift: 0
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvert24to8(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask, uint32 blueMask,
- uint32 redShift, uint32 greenShift, uint32 blueShift)
-{
- const uint8 *srcptr;
- uint8 *dstptr;
- int i, j, k;
-
- srcptr = src;
- srcptr += (src_y * src_increment) + (src_x * 3);
-
- dstptr = (uint8 *)tof;
- dstptr += (y * line_increment) + x;
-
- for (i=0; i<h; i++) {
- for (j=0, k=0; j<w; j++) {
- uint8 blue = srcptr[k++];
- uint8 green = srcptr[k++];
- uint8 red = srcptr[k++];
- dstptr[j] = ((red >> redShift) & redMask) |
- ((green >> greenShift) & greenMask) |
- ((blue >> blueShift) & blueMask);
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterConvert16to8 --
- *
- * Convert pixels from depth 16/15 to depth 8 BGR, while copying from
- * source to destination.
- * For BGR233 and depth 16: redShift:13 greenShift:5
- * blueShift:3 Shift left
- * For BGR233 and depth 15: redShift:12 greenShift:4
- * blueShift:3 Shift left
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RasterConvert16to8(uint8 *tof, uint32 line_increment,
- const uint8 *src, uint32 src_increment,
- uint32 src_x, uint32 src_y,
- uint32 x, uint32 y, uint32 w, uint32 h,
- uint32 redMask, uint32 greenMask, uint32 blueMask,
- int redShift, int greenShift, int blueShift)
-{
- const uint16 *srcptr;
- uint8 *dstptr;
- int i, j;
-
- src_increment >>= 1;
- srcptr = (uint16 *)src;
- srcptr += (src_y * src_increment) + src_x;
-
- dstptr = (uint8 *)tof;
- dstptr += (y * line_increment) + x;
-
- for (i=0; i<h; i++) {
- for (j=0; j<w; j++) {
- uint16 pix = srcptr[j];
- dstptr[j] = (redMask & RasterShiftPixel(pix, redShift)) |
- (greenMask & RasterShiftPixel(pix, greenShift)) |
- (blueMask & RasterShiftPixel(pix, blueShift));
- }
- srcptr += src_increment;
- dstptr += line_increment;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterGetShiftFromMask --
- *
- * Caculate the shift from the mask. For example, if we want to
- * convert from 24 bpp to BGR233, then for greenShift, the green mask
- * is 11100, green bits in 24 bpp starts from bit 16, the green bits in
- * BGR233 starts from bit 6, then the shift is 16 - 6 = 10
- *
- * Results:
- * The shift
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static int
-RasterGetShiftFromMask(uint32 start, uint32 mask)
-{
- uint32 num = 0;
-
- while (mask) {
- mask = mask >> 1;
- num++;
- }
-
- return (int)start - (int)num;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * RasterShiftPixel --
- *
- * Shift the pixel. If the shift is negative, shift to left,
- * other, shift to right.
- *
- * Results:
- * The shifted data
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-uint32
-RasterShiftPixel(uint32 pixel, int shift)
-{
- if (shift < 0) {
- return pixel << -shift;
- } else {
- return pixel >> shift;
- }
-}
+++ /dev/null
-################################################################################
-### Copyright 2008 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
-################################################################################
-
-noinst_LTLIBRARIES = libRegion.la
-
-libRegion_la_SOURCES =
-libRegion_la_SOURCES += region.c
+++ /dev/null
-/* **********************************************************
- * Copyright (C) 2002 VMware, Inc.
- * All Rights Reserved
- * **********************************************************/
-
-/* $XFree86: xc/programs/Xserver/mi/miregion.c,v 1.8 2001/12/14 20:00:26 dawes Exp $ */
-/***********************************************************
-
-Copyright 1987, 1988, 1989, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987, 1988, 1989 by
-Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-/* $Xorg: miregion.c,v 1.4 2001/02/09 02:05:21 xorgcvs Exp $ */
-
-/* The panoramix components contained the following notice */
-/*****************************************************************
-
-Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
-BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of Digital Equipment Corporation
-shall not be used in advertising or otherwise to promote the sale, use or other
-dealings in this Software without prior written authorization from Digital
-Equipment Corporation.
-
-******************************************************************/
-
-/*
- * miregion.c --
- *
- * This is a slightly modified copy of miregion.c from the XFree86 4.3.0
- * distribution: See http://www.xfree86.org, and the file
- * xc/programs/Xserver/mi/miregion.c.
- *
- * ChangeLog:
- *
- * 07/10/2003 rrdharan - removed X11 dependencies
- * - added prototype declarations for
- * miSetExtents and miFindMaxBands to prevent
- * compilation warnings
- * - #define assert ASSERT
- * - added FILECODE and comments
- * 09/01/2003 rrdharan - added initial support for accelerated
- * operations: all rectangles now have a
- * RectInfo struct associated with them that
- * contains metadata for the rectangle. See the
- * explanation of extensions below.
- * 08/02/2005 akan - fixed conflicting definition of MINSHORT
- * and MAXSHORT with winnt.h
- * 04/03/2007 shelleygong - use int instead of short for data
- * inside the region *
- * 02/12/2010 michael - Since coordinates are kept as ints, coordinate
- * values shouldn't be clamped to the range of short. I removed R_{MIN,MAX}SHORT
- * and changed clamping to be in the range R_MININT..R_MAXINT instead.
- * Since some code does "n < R_MININT" and "n > R_MAXINT", R_MININT must be
- * greater than INT_MIN and R_MAXINT must be less than INT_MAX.
- *
- * 03/08/2010 amarp - xalloc conflicts with boost macros. Move it
- * out of the header into the implementation
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-
-#include "region.h"
-
-void miSetExtents(RegionPtr pReg);
-int miFindMaxBand(RegionPtr prgn);
-
-#define good(reg) ASSERT(miValidRegion(reg))
-#define xalloc(n) malloc(n)
-
-/*
- * The functions in this file implement the Region abstraction used extensively
- * throughout the X11 sample server. A Region is simply a set of disjoint
- * (non-overlapping) rectangles, plus an "extent" rectangle which is the
- * smallest single rectangle that contains all the non-overlapping rectangles.
- *
- * A Region is implemented as a "y-x-banded" array of rectangles. This array
- * imposes two degrees of order. First, all rectangles are sorted by top side
- * y coordinate first (y1), and then by left side x coordinate (x1).
- *
- * Furthermore, the rectangles are grouped into "bands". Each rectangle in a
- * band has the same top y coordinate (y1), and each has the same bottom y
- * coordinate (y2). Thus all rectangles in a band differ only in their left
- * and right side (x1 and x2). Bands are implicit in the array of rectangles:
- * there is no separate list of band start pointers.
- *
- * The y-x band representation does not minimize rectangles. In particular,
- * if a rectangle vertically crosses a band (the rectangle has scanlines in
- * the y1 to y2 area spanned by the band), then the rectangle may be broken
- * down into two or more smaller rectangles stacked one atop the other.
- *
- * ----------- -----------
- * | | | | band 0
- * | | -------- ----------- --------
- * | | | | in y-x banded | | | | band 1
- * | | | | form is | | | |
- * ----------- | | ----------- --------
- * | | | | band 2
- * -------- --------
- *
- * An added constraint on the rectangles is that they must cover as much
- * horizontal area as possible: no two rectangles within a band are allowed
- * to touch.
- *
- * Whenever possible, bands will be merged together to cover a greater vertical
- * distance (and thus reduce the number of rectangles). Two bands can be merged
- * only if the bottom of one touches the top of the other and they have
- * rectangles in the same places (of the same width, of course).
- *
- * Adam de Boor wrote most of the original region code. Joel McCormack
- * substantially modified or rewrote most of the core arithmetic routines,
- * and added miRegionValidate in order to support several speed improvements
- * to miValidateTree. Bob Scheifler changed the representation to be more
- * compact when empty or a single rectangle, and did a bunch of gratuitous
- * reformatting.
- */
-
-/*
- * Accelerated Operation Support (09/03/03, rrdharan):
- *
- * We've extended the region code to support regions consisting of a mix
- * of update rectangles and "accelerated" operations (e.g. Fill). The
- * way it works is pretty straightforward, and the behavior should be
- * identical to the original region code when only update rectangles are
- * involved.
- *
- * Each rectangle now has a RectInfo structure member; this structure
- * indicates the type of the rectangle and carries any relevant metadata,
- * e.g. for a Fill, the rop and color. For each region operator, e.g.
- * miUnion, miIntersect, we treat the two source operands as layers,
- * where the first operand is the bottom layer and the second is the top.
- * Operations in the top layer stencil out the bottom layer. Note that we
- * still maintain the fundamental banding property of the regions.
- *
- * For clarification, consider the example below, where region 1 (the
- * bottom layer) consists of two updates and region 2 (the top layer)
- * consists of two fills. The union of the two regions results in a new
- * region where the fill operations have been stencilled into the
- * previous update rectangles, producing a new list of updates and fills.
- * The chief advantage of this approach is that it provides
- * order-independence; i.e. after any region operation has completed,
- * we can scan out the contents of the region and mapp the rectangles
- * onto their corresponding drawing operations in any order and still end
- * up with the correct result.
- *
- * Note that because we still enforce the banding rules, we pass up
- * opportunities for further optimization, (see comments on this in the
- * original documentation above).
- *
- * Region 1 (bottom): Region 2 (top):
- *
- * ----------------------- -----------------------
- * |------------ | | |
- * ||U | | | |
- * || | | | -------------- |
- * |------------ | | |F | |
- * | | | | | |
- * | | (union) | | | |
- * | -------------| | -------------- |
- * | |U || | |
- * | | || | ------ |
- * | | || | |F | |
- * | -------------| | ------ |
- * ----------------------- -----------------------
- *
- *
- * = New Region:
- *
- * -----------------------
- * |------------ |
- * ||U | |
- * ||---------------- |
- * ||U |F | |
- * |----------------- |
- * | |F | |
- * | -------------- |
- * | -------------|
- * | |U ||
- * | |-----------||
- * | |U |F |||
- * | -------------|
- * -----------------------
- *
- */
-
-/* true iff two Boxes overlap */
-#define EXTENTCHECK RECT_EXTENTCHECK
-
-/* true iff (x,y) is in Box */
-#define INBOX(r,x,y) \
- ( ((r)->x2 > x) && \
- ((r)->x1 <= x) && \
- ((r)->y2 > y) && \
- ((r)->y1 <= y) )
-
-/* true iff Box r1 contains Box r2 */
-#define SUBSUMES(r1,r2) \
- ( ((r1)->x1 <= (r2)->x1) && \
- ((r1)->x2 >= (r2)->x2) && \
- ((r1)->y1 <= (r2)->y1) && \
- ((r1)->y2 >= (r2)->y2) )
-
-#define min(a, b) (((a) < (b)) ? (a) : (b))
-#define max(a, b) (((a) > (b)) ? (a) : (b))
-
-#define xallocData(n) (RegDataPtr)malloc(REGION_SZOF(n))
-#define xfreeData(reg) if ((reg)->data && (reg)->data->size) \
- free((reg)->data)
-
-#define RECTALLOC_BAIL(pReg,n,bail) \
-if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
- if (!miRectAlloc(pReg, n)) { goto bail; }
-
-#define RECTALLOC(pReg,n) \
-if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
- if (!miRectAlloc(pReg, n)) { return FALSE; }
-
-#define ADDRECT(pNextRect,nx1,ny1,nx2,ny2,inf) \
-{ \
- pNextRect->x1 = nx1; \
- pNextRect->y1 = ny1; \
- pNextRect->x2 = nx2; \
- pNextRect->y2 = ny2; \
- pNextRect->info = inf; \
- pNextRect++; \
-}
-
-#define NEWRECT(pReg,pNextRect,nx1,ny1,nx2,ny2,inf) \
-{ \
- if (!(pReg)->data || ((pReg)->data->numRects == (pReg)->data->size))\
- { \
- if (!miRectAlloc(pReg, 1)) \
- return FALSE; \
- pNextRect = REGION_TOP(pReg); \
- } \
- ADDRECT(pNextRect,nx1,ny1,nx2,ny2,inf); \
- pReg->data->numRects++; \
- ASSERT(pReg->data->numRects<=pReg->data->size); \
-}
-
-
-#define DOWNSIZE(reg,numRects) \
-if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
-{ \
- RegDataPtr NewData; \
- NewData = (RegDataPtr)xrealloc((reg)->data, REGION_SZOF(numRects)); \
- if (NewData) \
- { \
- NewData->size = (numRects); \
- (reg)->data = NewData; \
- } \
-}
-
-BoxRec miEmptyBox = {0, 0, 0, 0};
-RegDataRec miEmptyData = {0, 0};
-
-RegDataRec miBrokenData = {0, 0};
-RegionRec miBrokenRegion = { { 0, 0, 0, 0 }, &miBrokenData };
-
-
-int
-miPrintRegion(RegionPtr rgn)
-{
- int num, size;
- register int i;
- BoxPtr rects;
-
- num = REGION_NUM_RECTS(rgn);
- size = REGION_SIZE(rgn);
- rects = REGION_RECTS(rgn);
- Warning("num: %d size: %d\n", num, size);
- Warning("extents: %d %d %d %d\n",
- rgn->extents.x1, rgn->extents.y1, rgn->extents.x2, rgn->extents.y2);
- for (i = 0; i < num; i++) {
- Warning("%4d %4d %4d %4d",
- rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);
- switch(rects[i].info.type) {
- case UpdateRect:
- Warning(" UpdateRect ");
- break;
- case ROPFillRect:
- Warning(" ROPFillRect 0x%08x", rects[i].info.ROPFill.color);
- break;
- case Present3dRect:
- Warning(" Present3DRect 0x%x src(%d, %d)",
- rects[i].info.Present3d.sid,
- rects[i].info.Present3d.srcx, rects[i].info.Present3d.srcy);
- break;
- case LockRect:
- Warning(" LockRect ");
- case FenceRect:
- Warning(" FenceRect fence: 0x%x", rects[i].info.Fence.fenceId);
- default:
- Warning(" UNKNOWN!");
- break;
- }
- Warning("\n");
- }
- Warning("\n");
- return(num);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * miRectInfosEqual --
- *
- * Takes pointers to two RectInfo structures and compares them for
- * equality based on their type and data: e.g. updates are always equal,
- * fills are equal only if the rop and color match.
- *
- * Results:
- * TRUE if the two RectInfo structures match, FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE Bool
-miRectInfosEqual(RectInfo *info1,
- RectInfo *info2)
-{
- if (info1->type != info2->type) {
- return FALSE;
- }
-
- switch (info1->type) {
- case UpdateRect:
- case LockRect:
- return TRUE;
- case ROPFillRect:
- return (info1->ROPFill.rop == info2->ROPFill.rop &&
- info1->ROPFill.color == info2->ROPFill.color);
- case Present3dRect:
- return (info1->Present3d.sid == info2->Present3d.sid &&
- info1->Present3d.srcx == info2->Present3d.srcx &&
- info1->Present3d.srcy == info2->Present3d.srcy);
- case FenceRect:
- return (info1->Fence.fenceId == info2->Fence.fenceId);
- default:
- NOT_IMPLEMENTED();
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * miRectInfosVertAdjacent --
- *
- * Takes pointers to two RectInfo structures of type Present3dRect and
- * decides whether they're vertically mergeable (same sid, same srcx,
- * srcy adjacent).
- *
- * Results:
- * TRUE if the two RectInfo structures are adjacent, FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE Bool
-miRectInfosVertAdjacent(RectInfo *info1,
- int y1,
- RectInfo *info2,
- int y2)
-{
- if (info1->type == Present3dRect && info2->type == Present3dRect) {
- return (info1->Present3d.sid == info2->Present3d.sid &&
- info1->Present3d.srcx == info2->Present3d.srcx &&
- info1->Present3d.srcy - y1 == info2->Present3d.srcy - y2);
- } else {
- return miRectInfosEqual(info1, info2);
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * miRectInfosHorzAdjacent --
- *
- * Takes pointers to two RectInfo structures of type Present3dRect
- * and decides whether they're horizontally mergeable (same sid,
- * same srcy, srcx adjacent).
- *
- * Results:
- * TRUE if the two RectInfo structures are adjacent, FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE Bool
-miRectInfosHorzAdjacent(RectInfo *info1,
- int x1,
- RectInfo *info2,
- int x2)
-{
- if (info1->type == Present3dRect && info2->type == Present3dRect) {
- return (info1->Present3d.sid == info2->Present3d.sid &&
- info1->Present3d.srcx - x1 == info2->Present3d.srcx - x2 &&
- info1->Present3d.srcy == info2->Present3d.srcy);
- } else {
- return miRectInfosEqual(info1, info2);
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * miRectInfoAdjustForSplit --
- *
- * Adjusts the type-specific data in the RectInfo to be correct
- * for a split that moves the upper left corner of the associated
- * rectangle from (oldX, oldY) to (newX, newY).
- *
- * Results:
- * None.
- *
- * Side effects:
- * Fiddles with *info as described above.
- *
- *----------------------------------------------------------------------------
- */
-
-static INLINE void
-miRectInfoAdjustForSplit(RectInfo *info,
- int oldX,
- int oldY,
- int newX,
- int newY)
-{
- ASSERT(newX >= oldX);
- ASSERT(newY >= oldY);
-
- if (info->type == Present3dRect) {
- info->Present3d.srcx += newX - oldX;
- info->Present3d.srcy += newY - oldY;
- }
-}
-
-
-Bool
-miRegionsEqual(RegionPtr reg1,
- RegionPtr reg2)
-{
- int i;
- BoxPtr rects1, rects2;
-
- if (reg1->extents.x1 != reg2->extents.x1) return FALSE;
- if (reg1->extents.x2 != reg2->extents.x2) return FALSE;
- if (reg1->extents.y1 != reg2->extents.y1) return FALSE;
- if (reg1->extents.y2 != reg2->extents.y2) return FALSE;
- if (REGION_NUM_RECTS(reg1) != REGION_NUM_RECTS(reg2)) return FALSE;
-
- rects1 = REGION_RECTS(reg1);
- rects2 = REGION_RECTS(reg2);
- for (i = 0; i != REGION_NUM_RECTS(reg1); i++) {
- if (rects1[i].x1 != rects2[i].x1) return FALSE;
- if (rects1[i].x2 != rects2[i].x2) return FALSE;
- if (rects1[i].y1 != rects2[i].y1) return FALSE;
- if (rects1[i].y2 != rects2[i].y2) return FALSE;
- if (!miRectInfosEqual(&rects1[i].info, &rects2[i].info)) return FALSE;
- }
- return TRUE;
-}
-
-
-Bool
-miValidRegion(RegionPtr reg)
-{
- register int i, numRects;
-
- if ((reg->extents.x1 > reg->extents.x2) ||
- (reg->extents.y1 > reg->extents.y2))
- return FALSE;
- numRects = REGION_NUM_RECTS(reg);
- if (!numRects)
- return ((reg->extents.x1 == reg->extents.x2) &&
- (reg->extents.y1 == reg->extents.y2) &&
- (reg->data->size || (reg->data == &miEmptyData)));
- else if (numRects == 1)
- return (RECTINFO_ISVALID((reg->extents.info)) && !reg->data);
- else
- {
- register BoxPtr pboxP, pboxN;
- BoxRec box;
-
- pboxP = REGION_RECTS(reg);
- box = *pboxP;
- box.y2 = pboxP[numRects-1].y2;
- pboxN = pboxP + 1;
- for (i = numRects; --i > 0; pboxP++, pboxN++)
- {
- if (!RECTINFO_ISVALID(pboxP->info)) {
- return FALSE;
- }
- if ((pboxN->x1 >= pboxN->x2) ||
- (pboxN->y1 >= pboxN->y2))
- return FALSE;
- if (pboxN->x1 < box.x1)
- box.x1 = pboxN->x1;
- if (pboxN->x2 > box.x2)
- box.x2 = pboxN->x2;
- if ((pboxN->y1 < pboxP->y1) ||
- ((pboxN->y1 == pboxP->y1) &&
- ((pboxN->x1 < pboxP->x2) || (pboxN->y2 != pboxP->y2))))
- return FALSE;
- }
- return ((box.x1 == reg->extents.x1) &&
- (box.x2 == reg->extents.x2) &&
- (box.y1 == reg->extents.y1) &&
- (box.y2 == reg->extents.y2));
- }
-}
-
-
-/*****************************************************************
- * RegionCreate(rect, size)
- * This routine does a simple malloc to make a structure of
- * REGION of "size" number of rectangles.
- *****************************************************************/
-
-RegionPtr
-miRegionCreate(rect, size)
- BoxPtr rect;
- int size;
-{
- register RegionPtr pReg;
-
- pReg = (RegionPtr)xalloc(sizeof(RegionRec));
- if (!pReg)
- return &miBrokenRegion;
- if (rect)
- {
- pReg->extents = *rect;
- pReg->data = (RegDataPtr)NULL;
- }
- else
- {
- pReg->extents = miEmptyBox;
- if ((size > 1) && (pReg->data = xallocData(size)))
- {
- pReg->data->size = size;
- pReg->data->numRects = 0;
- }
- else
- pReg->data = &miEmptyData;
- }
- return(pReg);
-}
-
-/*****************************************************************
- * RegionInit(pReg, rect, size)
- * Outer region rect is statically allocated.
- *****************************************************************/
-
-void
-miRegionInit(pReg, rect, size)
- RegionPtr pReg;
- BoxPtr rect;
- int size;
-{
- if (rect)
- {
- pReg->extents = *rect;
- pReg->data = (RegDataPtr)NULL;
- }
- else
- {
- pReg->extents = miEmptyBox;
- if ((size > 1) && (pReg->data = xallocData(size)))
- {
- pReg->data->size = size;
- pReg->data->numRects = 0;
- }
- else
- pReg->data = &miEmptyData;
- }
-}
-
-void
-miRegionDestroy(pReg)
- RegionPtr pReg;
-{
- good(pReg);
- xfreeData(pReg);
- if (pReg != &miBrokenRegion)
- xfree(pReg);
-}
-
-void
-miRegionUninit(pReg)
- RegionPtr pReg;
-{
- good(pReg);
- xfreeData(pReg);
-}
-
-Bool
-miRegionBreak (pReg)
- RegionPtr pReg;
-{
- xfreeData (pReg);
- pReg->extents = miEmptyBox;
- pReg->data = &miBrokenData;
- return FALSE;
-}
-
-Bool
-miRectAlloc(
- register RegionPtr pRgn,
- int n)
-{
- RegDataPtr data;
-
- if (!pRgn->data)
- {
- n++;
- pRgn->data = xallocData(n);
- if (!pRgn->data)
- return miRegionBreak (pRgn);
- pRgn->data->numRects = 1;
- *REGION_BOXPTR(pRgn) = pRgn->extents;
- }
- else if (!pRgn->data->size)
- {
- pRgn->data = xallocData(n);
- if (!pRgn->data)
- return miRegionBreak (pRgn);
- pRgn->data->numRects = 0;
- }
- else
- {
- if (n == 1)
- {
- n = pRgn->data->numRects;
- if (n > 500) /* XXX pick numbers out of a hat */
- n = 250;
- }
- n += pRgn->data->numRects;
- data = (RegDataPtr)xrealloc(pRgn->data, REGION_SZOF(n));
- if (!data)
- return miRegionBreak (pRgn);
- pRgn->data = data;
- }
- pRgn->data->size = n;
- return TRUE;
-}
-
-Bool
-miRegionCopy(dst, src)
- register RegionPtr dst;
- register RegionPtr src;
-{
- good(dst);
- good(src);
- if (dst == src)
- return TRUE;
- dst->extents = src->extents;
- if (!src->data || !src->data->size)
- {
- xfreeData(dst);
- dst->data = src->data;
- return TRUE;
- }
- if (!dst->data || (dst->data->size < src->data->numRects))
- {
- xfreeData(dst);
- dst->data = xallocData(src->data->numRects);
- if (!dst->data)
- return miRegionBreak (dst);
- dst->data->size = src->data->numRects;
- }
- dst->data->numRects = src->data->numRects;
- memmove((char *)REGION_BOXPTR(dst),(char *)REGION_BOXPTR(src),
- dst->data->numRects * sizeof(BoxRec));
- return TRUE;
-}
-
-
-/*======================================================================
- * Generic Region Operator
- *====================================================================*/
-
-/*-
- *-----------------------------------------------------------------------
- * miCoalesce --
- * Attempt to merge the boxes in the current band with those in the
- * previous one. We are guaranteed that the current band extends to
- * the end of the rects array. Used only by miRegionOp.
- *
- * Results:
- * The new index for the previous band.
- *
- * Side Effects:
- * If coalescing takes place:
- * - rectangles in the previous band will have their y2 fields
- * altered.
- * - pReg->data->numRects will be decreased.
- *
- *-----------------------------------------------------------------------
- */
-INLINE static int
-miCoalesce (
- register RegionPtr pReg, /* Region to coalesce */
- int prevStart, /* Index of start of previous band */
- int curStart) /* Index of start of current band */
-{
- register BoxPtr pPrevBox; /* Current box in previous band */
- register BoxPtr pCurBox; /* Current box in current band */
- register int numRects; /* Number rectangles in both bands */
- register int y2; /* Bottom of current band */
- /*
- * Figure out how many rectangles are in the band.
- */
- numRects = curStart - prevStart;
- ASSERT(numRects == pReg->data->numRects - curStart);
-
- if (!numRects) return curStart;
-
- /*
- * The bands may only be coalesced if the bottom of the previous
- * matches the top scanline of the current.
- */
- pPrevBox = REGION_BOX(pReg, prevStart);
- pCurBox = REGION_BOX(pReg, curStart);
- if (pPrevBox->y2 != pCurBox->y1) return curStart;
-
- /*
- * Make sure the bands have boxes in the same places. This
- * assumes that boxes have been added in such a way that they
- * cover the most area possible. I.e. two boxes in a band must
- * have some horizontal space between them.
- */
- y2 = pCurBox->y2;
-
- do {
- if ((pPrevBox->x1 != pCurBox->x1) || (pPrevBox->x2 != pCurBox->x2)) {
- return (curStart);
- }
-
- if (!(miRectInfosVertAdjacent(&pPrevBox->info, pPrevBox->y1,
- &pCurBox->info, pCurBox->y1))) {
- return (curStart);
- }
-
- pPrevBox++;
- pCurBox++;
- numRects--;
- } while (numRects);
-
- /*
- * The bands may be merged, so set the bottom y of each box
- * in the previous band to the bottom y of the current band.
- */
- numRects = curStart - prevStart;
- pReg->data->numRects -= numRects;
- do {
- pPrevBox--;
- pPrevBox->y2 = y2;
- numRects--;
- } while (numRects);
- return prevStart;
-}
-
-
-/* Quicky macro to avoid trivial reject procedure calls to miCoalesce */
-
-#define Coalesce(newReg, prevBand, curBand) \
- if (curBand - prevBand == newReg->data->numRects - curBand) { \
- prevBand = miCoalesce(newReg, prevBand, curBand); \
- } else { \
- prevBand = curBand; \
- }
-
-/*-
- *-----------------------------------------------------------------------
- * miAppendNonO --
- * Handle a non-overlapping band for the union and subtract operations.
- * Just adds the (top/bottom-clipped) rectangles into the region.
- * Doesn't have to check for subsumption or anything.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * pReg->data->numRects is incremented and the rectangles overwritten
- * with the rectangles we're passed.
- *
- *-----------------------------------------------------------------------
- */
-
-INLINE static Bool
-miAppendNonO (
- register RegionPtr pReg,
- register BoxPtr r,
- BoxPtr rEnd,
- register int y1,
- register int y2)
-{
- register BoxPtr pNextRect;
- register int newRects;
-
- newRects = (int) (rEnd - r);
-
- ASSERT(y1 < y2);
- ASSERT(newRects != 0);
-
- /* Make sure we have enough space for all rectangles to be added */
- RECTALLOC(pReg, newRects);
- pNextRect = REGION_TOP(pReg);
- pReg->data->numRects += newRects;
- do {
- RectInfo info = r->info;
- ASSERT(r->x1 < r->x2);
- miRectInfoAdjustForSplit(&info, 0, r->y1, 0, y1);
- ADDRECT(pNextRect, r->x1, y1, r->x2, y2, info);
- r++;
- } while (r != rEnd);
-
- return TRUE;
-}
-
-#define FindBand(r, rBandEnd, rEnd, ry1) \
-{ \
- ry1 = r->y1; \
- rBandEnd = r+1; \
- while ((rBandEnd != rEnd) && (rBandEnd->y1 == ry1)) { \
- rBandEnd++; \
- } \
-}
-
-#define AppendRegions(newReg, r, rEnd) \
-{ \
- int newRects; \
- if ((newRects = (int) (rEnd - r))) { \
- RECTALLOC(newReg, newRects); \
- memmove((char *)REGION_TOP(newReg),(char *)r, \
- newRects * sizeof(BoxRec)); \
- newReg->data->numRects += newRects; \
- } \
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miRegionOp --
- * Apply an operation to two regions. Called by miUnion, miInverse,
- * miSubtract, miIntersect.... Both regions MUST have at least one
- * rectangle, and cannot be the same object.
- *
- * Results:
- * TRUE if successful.
- *
- * Side Effects:
- * The new region is overwritten.
- * pOverlap set to TRUE if overlapFunc ever returns TRUE.
- *
- * Notes:
- * The idea behind this function is to view the two regions as sets.
- * Together they cover a rectangle of area that this function divides
- * into horizontal bands where points are covered only by one region
- * or by both. For the first case, miAppendNonO is called with
- * each the band and the band's upper and lower extents. For the
- * second, the overlapFunc is called to process the entire band. It
- * is responsible for clipping the rectangles in the band, though
- * this function provides the boundaries.
- * At the end of each band, the new region is coalesced, if possible,
- * to reduce the number of rectangles in the region.
- *
- *-----------------------------------------------------------------------
- */
-
-typedef Bool (*OverlapProcPtr)(
- RegionPtr pReg,
- BoxPtr r1,
- BoxPtr r1End,
- BoxPtr r2,
- BoxPtr r2End,
- int y1,
- int y2,
- Bool *pOverlap);
-
-static Bool miIntersectO(RegionPtr pReg, BoxPtr r1, BoxPtr r1End, BoxPtr r2,
- BoxPtr r2End, int y1, int y2, Bool *pOverlap);
-static Bool miUnionO(RegionPtr pReg, BoxPtr r1, BoxPtr r1End, BoxPtr r2,
- BoxPtr r2End, int y1, int y2, Bool *pOverlap);
-static Bool miSubtractO(RegionPtr pReg, BoxPtr r1, BoxPtr r1End, BoxPtr r2,
- BoxPtr r2End, int y1, int y2, Bool *pOverlap);
-
-static Bool
-miRegionOp(
- RegionPtr newReg, /* Place to store result */
- RegionPtr reg1, /* First region in operation */
- RegionPtr reg2, /* 2d region in operation */
- OverlapProcPtr overlapFunc, /* Function to call for over-
- * lapping bands */
- Bool appendNon1, /* Append non-overlapping bands */
- /* in region 1 ? */
- Bool appendNon2, /* Append non-overlapping bands */
- /* in region 2 ? */
- Bool *pOverlap)
-{
- register BoxPtr r1; /* Pointer into first region */
- register BoxPtr r2; /* Pointer into 2d region */
- BoxPtr r1End; /* End of 1st region */
- BoxPtr r2End; /* End of 2d region */
- int ybot; /* Bottom of intersection */
- int ytop; /* Top of intersection */
- RegDataPtr oldData; /* Old data for newReg */
- int prevBand; /* Index of start of
- * previous band in newReg */
- int curBand; /* Index of start of current
- * band in newReg */
- register BoxPtr r1BandEnd; /* End of current band in r1 */
- register BoxPtr r2BandEnd; /* End of current band in r2 */
- int top; /* Top of non-overlapping band */
- int bot; /* Bottom of non-overlapping band*/
- register int r1y1; /* Temps for r1->y1 and r2->y1 */
- register int r2y1;
- int newSize;
- int numRects;
-
- /*
- * Break any region computed from a broken region
- */
- if (REGION_NAR (reg1) || REGION_NAR(reg2))
- return miRegionBreak (newReg);
-
- /*
- * Initialization:
- * set r1, r2, r1End and r2End appropriately, save the rectangles
- * of the destination region until the end in case it's one of
- * the two source regions, then mark the "new" region empty, allocating
- * another array of rectangles for it to use.
- */
-
- r1 = REGION_RECTS(reg1);
- newSize = REGION_NUM_RECTS(reg1);
- r1End = r1 + newSize;
- numRects = REGION_NUM_RECTS(reg2);
- r2 = REGION_RECTS(reg2);
- r2End = r2 + numRects;
- ASSERT(r1 != r1End);
- ASSERT(r2 != r2End);
-
- oldData = (RegDataPtr)NULL;
- if (((newReg == reg1) && (newSize > 1)) ||
- ((newReg == reg2) && (numRects > 1)))
- {
- oldData = newReg->data;
- newReg->data = &miEmptyData;
- }
- /* guess at new size */
- if (numRects > newSize)
- newSize = numRects;
- newSize <<= 1;
- if (!newReg->data)
- newReg->data = &miEmptyData;
- else if (newReg->data->size)
- newReg->data->numRects = 0;
- if (newSize > newReg->data->size)
- if (!miRectAlloc(newReg, newSize))
- return FALSE;
-
- /*
- * Initialize ybot.
- * In the upcoming loop, ybot and ytop serve different functions depending
- * on whether the band being handled is an overlapping or non-overlapping
- * band.
- * In the case of a non-overlapping band (only one of the regions
- * has points in the band), ybot is the bottom of the most recent
- * intersection and thus clips the top of the rectangles in that band.
- * ytop is the top of the next intersection between the two regions and
- * serves to clip the bottom of the rectangles in the current band.
- * For an overlapping band (where the two regions intersect), ytop clips
- * the top of the rectangles of both regions and ybot clips the bottoms.
- */
-
- ybot = min(r1->y1, r2->y1);
-
- /*
- * prevBand serves to mark the start of the previous band so rectangles
- * can be coalesced into larger rectangles. qv. miCoalesce, above.
- * In the beginning, there is no previous band, so prevBand == curBand
- * (curBand is set later on, of course, but the first band will always
- * start at index 0). prevBand and curBand must be indices because of
- * the possible expansion, and resultant moving, of the new region's
- * array of rectangles.
- */
- prevBand = 0;
-
- do {
- /*
- * This algorithm proceeds one source-band (as opposed to a
- * destination band, which is determined by where the two regions
- * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
- * rectangle after the last one in the current band for their
- * respective regions.
- */
- ASSERT(r1 != r1End);
- ASSERT(r2 != r2End);
-
- FindBand(r1, r1BandEnd, r1End, r1y1);
- FindBand(r2, r2BandEnd, r2End, r2y1);
-
- /*
- * First handle the band that doesn't intersect, if any.
- *
- * Note that attention is restricted to one band in the
- * non-intersecting region at once, so if a region has n
- * bands between the current position and the next place it overlaps
- * the other, this entire loop will be passed through n times.
- */
- if (r1y1 < r2y1) {
- if (appendNon1) {
- top = max(r1y1, ybot);
- bot = min(r1->y2, r2y1);
- if (top != bot) {
- curBand = newReg->data->numRects;
- miAppendNonO(newReg, r1, r1BandEnd, top, bot);
- Coalesce(newReg, prevBand, curBand);
- }
- }
- ytop = r2y1;
- } else if (r2y1 < r1y1) {
- if (appendNon2) {
- top = max(r2y1, ybot);
- bot = min(r2->y2, r1y1);
- if (top != bot) {
- curBand = newReg->data->numRects;
- miAppendNonO(newReg, r2, r2BandEnd, top, bot);
- Coalesce(newReg, prevBand, curBand);
- }
- }
- ytop = r1y1;
- } else {
- ytop = r1y1;
- }
-
- /*
- * Now see if we've hit an intersecting band. The two bands only
- * intersect if ybot > ytop
- */
- ybot = min(r1->y2, r2->y2);
- if (ybot > ytop) {
- curBand = newReg->data->numRects;
- (* overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot,
- pOverlap);
- Coalesce(newReg, prevBand, curBand);
- }
-
- /*
- * If we've finished with a band (y2 == ybot) we skip forward
- * in the region to the next band.
- */
- if (r1->y2 == ybot) r1 = r1BandEnd;
- if (r2->y2 == ybot) r2 = r2BandEnd;
-
- } while (r1 != r1End && r2 != r2End);
-
- /*
- * Deal with whichever region (if any) still has rectangles left.
- *
- * We only need to worry about banding and coalescing for the very first
- * band left. After that, we can just group all remaining boxes,
- * regardless of how many bands, into one final append to the list.
- */
-
- if ((r1 != r1End) && appendNon1) {
- /* Do first nonOverlap1Func call, which may be able to coalesce */
- FindBand(r1, r1BandEnd, r1End, r1y1);
- curBand = newReg->data->numRects;
- miAppendNonO(newReg, r1, r1BandEnd, max(r1y1, ybot), r1->y2);
- Coalesce(newReg, prevBand, curBand);
- /* Just append the rest of the boxes */
- AppendRegions(newReg, r1BandEnd, r1End);
-
- } else if ((r2 != r2End) && appendNon2) {
- /* Do first nonOverlap2Func call, which may be able to coalesce */
- FindBand(r2, r2BandEnd, r2End, r2y1);
- curBand = newReg->data->numRects;
- miAppendNonO(newReg, r2, r2BandEnd, max(r2y1, ybot), r2->y2);
- Coalesce(newReg, prevBand, curBand);
- /* Append rest of boxes */
- AppendRegions(newReg, r2BandEnd, r2End);
- }
-
- if (oldData)
- xfree(oldData);
-
- if (!(numRects = newReg->data->numRects))
- {
- xfreeData(newReg);
- newReg->data = &miEmptyData;
- }
- else if (numRects == 1)
- {
- newReg->extents = *REGION_BOXPTR(newReg);
- xfreeData(newReg);
- newReg->data = (RegDataPtr)NULL;
- }
- else
- {
- DOWNSIZE(newReg, numRects);
- }
-
- return TRUE;
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miSetExtents --
- * Reset the extents of a region to what they should be. Called by
- * miSubtract and miIntersect as they can't figure it out along the
- * way or do so easily, as miUnion can.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * The region's 'extents' structure is overwritten.
- *
- *-----------------------------------------------------------------------
- */
-void
-miSetExtents (pReg)
- register RegionPtr pReg;
-{
- register BoxPtr pBox, pBoxEnd;
-
- if (!pReg->data)
- return;
- if (!pReg->data->size)
- {
- pReg->extents.x2 = pReg->extents.x1;
- pReg->extents.y2 = pReg->extents.y1;
- return;
- }
-
- pBox = REGION_BOXPTR(pReg);
- pBoxEnd = REGION_END(pReg);
-
- /*
- * Since pBox is the first rectangle in the region, it must have the
- * smallest y1 and since pBoxEnd is the last rectangle in the region,
- * it must have the largest y2, because of banding. Initialize x1 and
- * x2 from pBox and pBoxEnd, resp., as good things to initialize them
- * to...
- */
- pReg->extents.x1 = pBox->x1;
- pReg->extents.y1 = pBox->y1;
- pReg->extents.x2 = pBoxEnd->x2;
- pReg->extents.y2 = pBoxEnd->y2;
-
- ASSERT(pReg->extents.y1 < pReg->extents.y2);
- while (pBox <= pBoxEnd) {
- if (pBox->x1 < pReg->extents.x1)
- pReg->extents.x1 = pBox->x1;
- if (pBox->x2 > pReg->extents.x2)
- pReg->extents.x2 = pBox->x2;
- pBox++;
- };
-
- ASSERT(pReg->extents.x1 < pReg->extents.x2);
-}
-
-/*======================================================================
- * Region Intersection
- *====================================================================*/
-/*-
- *-----------------------------------------------------------------------
- * miIntersectO --
- * Handle an overlapping band for miIntersect.
- *
- * Results:
- * TRUE if successful.
- *
- * Side Effects:
- * Rectangles may be added to the region.
- *
- *-----------------------------------------------------------------------
- */
-/*ARGSUSED*/
-static Bool
-miIntersectO (
- register RegionPtr pReg,
- register BoxPtr r1,
- BoxPtr r1End,
- register BoxPtr r2,
- BoxPtr r2End,
- int y1,
- int y2,
- Bool *pOverlap)
-{
- register int x1;
- register int x2;
- register BoxPtr pNextRect;
-
- pNextRect = REGION_TOP(pReg);
-
- ASSERT(y1 < y2);
- ASSERT(r1 != r1End && r2 != r2End);
-
- do {
- x1 = max(r1->x1, r2->x1);
- x2 = min(r1->x2, r2->x2);
-
- /*
- * If there's any overlap between the two rectangles, add that overlap
- * to the new region, using r2's RectInfo for the new rectangle.
- */
- if (x1 < x2) {
- RectInfo info = r2->info;
-
- miRectInfoAdjustForSplit(&info, r2->x1, r2->y1, x1, y1);
- NEWRECT(pReg, pNextRect, x1, y1, x2, y2, info);
- }
-
- /*
- * Advance the pointer(s) with the leftmost right side, since the next
- * rectangle on that list may still overlap the other region's
- * current rectangle.
- */
- if (r1->x2 == x2) {
- r1++;
- }
- if (r2->x2 == x2) {
- r2++;
- }
- } while ((r1 != r1End) && (r2 != r2End));
-
- return TRUE;
-}
-
-
-Bool
-miIntersect(newReg, reg1, reg2)
- register RegionPtr newReg; /* destination Region */
- register RegionPtr reg1;
- register RegionPtr reg2; /* source regions */
-{
- good(reg1);
- good(reg2);
- good(newReg);
- /* check for trivial reject */
- if (REGION_NIL(reg1) || REGION_NIL(reg2) ||
- !EXTENTCHECK(®1->extents, ®2->extents))
- {
- /* Covers about 20% of all cases */
- xfreeData(newReg);
- newReg->extents.x2 = newReg->extents.x1;
- newReg->extents.y2 = newReg->extents.y1;
- if (REGION_NAR(reg1) || REGION_NAR(reg2))
- {
- newReg->data = &miBrokenData;
- return FALSE;
- }
- else
- newReg->data = &miEmptyData;
- }
- else if (!reg1->data && !reg2->data)
- {
- /* Covers about 80% of cases that aren't trivially rejected */
- newReg->extents.x1 = max(reg1->extents.x1, reg2->extents.x1);
- newReg->extents.y1 = max(reg1->extents.y1, reg2->extents.y1);
- newReg->extents.x2 = min(reg1->extents.x2, reg2->extents.x2);
- newReg->extents.y2 = min(reg1->extents.y2, reg2->extents.y2);
- newReg->extents.info = reg2->extents.info;
- miRectInfoAdjustForSplit(&newReg->extents.info,
- reg2->extents.x1, reg2->extents.y1,
- newReg->extents.x1, newReg->extents.y1);
- xfreeData(newReg);
- newReg->data = (RegDataPtr)NULL;
- }
- else if (!reg2->data && SUBSUMES(®2->extents, ®1->extents))
- {
- int i;
- Bool res;
-
- /*
- * Result is reg1 with reg2's info copied into all rectangles.
- */
- if ((res = miRegionCopy(newReg, reg1)))
- {
- newReg->extents.info = reg2->extents.info;
- miRectInfoAdjustForSplit(&newReg->extents.info,
- reg2->extents.x1, reg2->extents.y1,
- newReg->extents.x1, newReg->extents.y1);
- for (i = 0; i < newReg->data->numRects; i++)
- {
- BoxPtr box = REGION_BOX(newReg, i);
- box->info = reg2->extents.info;
- miRectInfoAdjustForSplit(&box->info,
- reg2->extents.x1, reg2->extents.y1,
- box->x1, box->y1);
- }
- }
- return res;
- }
- else if (!reg1->data && SUBSUMES(®1->extents, ®2->extents))
- {
- return miRegionCopy(newReg, reg2);
- }
- else if (reg1 == reg2)
- {
- return miRegionCopy(newReg, reg1);
- }
- else
- {
- /* General purpose intersection */
- Bool overlap; /* result ignored */
- if (!miRegionOp(newReg, reg1, reg2, miIntersectO, FALSE, FALSE,
- &overlap))
- return FALSE;
- miSetExtents(newReg);
- }
-
- good(newReg);
- return(TRUE);
-}
-
-#define MERGERECT(r) \
-{ \
- if (r->x1 <= x2) { \
- /* Merge with current rectangle */ \
- if (r->x1 < x2) *pOverlap = TRUE; \
- if (x2 < r->x2) x2 = r->x2; \
- } else { \
- /* Add current rectangle, start new one */ \
- NEWRECT(pReg, pNextRect, x1, y1, x2, y2); \
- x1 = r->x1; \
- x2 = r->x2; \
- } \
- r++; \
-}
-
-/*======================================================================
- * Region Union
- *====================================================================*/
-
-/*-
- *-----------------------------------------------------------------------
- * miUnionO --
- * Handle an overlapping band for the union operation. Picks the
- * left-most rectangle each time and merges it into the region.
- *
- * Results:
- * TRUE if successful.
- *
- * Side Effects:
- * pReg is overwritten.
- * pOverlap is set to TRUE if any boxes overlap.
- *
- *-----------------------------------------------------------------------
- */
-static Bool
-miUnionO (
- register RegionPtr pReg,
- register BoxPtr r1,
- BoxPtr r1End,
- register BoxPtr r2,
- BoxPtr r2End,
- int y1,
- int y2,
- Bool *pOverlap)
-{
- register BoxPtr pNextRect;
-
- RegionRec subReg;
- RegionRec tmpReg;
- BoxPtr pNextRectTmp;
- int x1, x2;
- RectInfo info;
-
- ASSERT (y1 < y2);
- ASSERT(r1 != r1End && r2 != r2End);
-
- miRegionInit(&subReg, NULL, (int) (r1End - r1));
- miRegionInit(&tmpReg, NULL, (int) (r1End - r1));
-
- pNextRectTmp = REGION_BOXPTR((&tmpReg));
-
- /*
- * XXX We compute the union as (reg 1 - reg 2) + (reg 2). Is there a
- * better way?
- */
- miSubtractO(&subReg, r1, r1End, r2, r2End, y1, y2, pOverlap);
-
- r1 = REGION_BOXPTR(&subReg);
- r1End = REGION_TOP(&subReg);
-
- /*
- * Add the new rectangles in the correct order into a temporary list
- */
- while (r1 != r1End || r2 != r2End) {
- if (r1 != r1End && (r2 == r2End || (r1->x1 < r2->x1))) {
- info = r1->info;
- if (y1 > r1->y1) {
- miRectInfoAdjustForSplit(&info,
- r1->x1, r1->y1,
- r1->x1, y1);
- }
- NEWRECT((&tmpReg), pNextRectTmp, r1->x1, y1, r1->x2, y2, info);
- r1++;
- } else {
- info = r2->info;
- if (y1 > r2->y1) {
- miRectInfoAdjustForSplit(&info,
- r2->x1, r2->y1,
- r2->x1, y1);
- }
- NEWRECT((&tmpReg), pNextRectTmp, r2->x1, y1, r2->x2, y2, info);
- r2++;
- }
- }
-
- /*
- * Copy the rectangles into the destination region, merging where possible
- */
- for (pNextRectTmp = REGION_BOXPTR(&tmpReg),
- x1 = pNextRectTmp->x1, x2 = pNextRectTmp->x2, info = pNextRectTmp->info,
- pNextRect = REGION_TOP(pReg);
- pNextRectTmp != REGION_TOP(&tmpReg);
- pNextRectTmp++) {
-
- if (pNextRectTmp->x1 > x2 ||
- !miRectInfosHorzAdjacent(&pNextRectTmp->info, pNextRectTmp->x1,
- &info, x1)) {
- NEWRECT(pReg, pNextRect, x1, y1, x2, y2, info);
- x1 = pNextRectTmp->x1;
- x2 = pNextRectTmp->x2;
- info = pNextRectTmp->info;
- } else {
- x2 = pNextRectTmp->x2;
- }
- }
-
- NEWRECT(pReg, pNextRect, x1, y1, x2, y2, info);
-
- xfreeData(&subReg);
- xfreeData(&tmpReg);
-
- return TRUE;
-}
-
-Bool
-miUnion(newReg, reg1, reg2)
- RegionPtr newReg; /* destination Region */
- register RegionPtr reg1;
- register RegionPtr reg2; /* source regions */
-{
- Bool overlap; /* result ignored */
-
- /* Return TRUE if some overlap between reg1, reg2 */
- good(reg1);
- good(reg2);
- good(newReg);
- /* checks all the simple cases */
-
- /*
- * Region 1 and 2 are the same
- */
- if (reg1 == reg2)
- {
- return miRegionCopy(newReg, reg1);
- }
-
- /*
- * Region 1 is empty
- */
- if (miIsRegionVoid(reg1))
- {
- if (REGION_NAR(reg1))
- return miRegionBreak (newReg);
- if (newReg != reg2)
- return miRegionCopy(newReg, reg2);
- return TRUE;
- }
-
- /*
- * Region 2 is empty
- */
- if (miIsRegionVoid(reg2))
- {
- if (REGION_NAR(reg2))
- return miRegionBreak (newReg);
- if (newReg != reg1)
- return miRegionCopy(newReg, reg1);
- return TRUE;
- }
-
- /*
- * Region 1 completely subsumes region 2
- *
- * We still need to do the complete union calculation, because reg 2
- * may have accelerated operations that need to be stencilled onto reg 1
- */
-
- /*
- if (!reg1->data && SUBSUMES(®1->extents, ®2->extents))
- {
- if (newReg != reg1)
- return miRegionCopy(newReg, reg1);
- return TRUE;
- }
- */
-
- /*
- * Region 2 completely subsumes region 1
- */
- if (!reg2->data && SUBSUMES(®2->extents, ®1->extents))
- {
- if (newReg != reg2)
- return miRegionCopy(newReg, reg2);
- return TRUE;
- }
-
- if (!miRegionOp(newReg, reg1, reg2, miUnionO, TRUE, TRUE, &overlap))
- return FALSE;
-
- /*
- * This previously failed when we called REGION_NIL on reg1 and reg2;
- * a region could be !REGION_NIL but have an extent, say 0, 0, 0, 0,
- * which would then overwrite newReg with an invalid extent.
- *
- * Using miIsRegionVoid() instead of testing REGION_NIL fixes that
- * bug.
- */
- newReg->extents.x1 = min(reg1->extents.x1, reg2->extents.x1);
- newReg->extents.y1 = min(reg1->extents.y1, reg2->extents.y1);
- newReg->extents.x2 = max(reg1->extents.x2, reg2->extents.x2);
- newReg->extents.y2 = max(reg1->extents.y2, reg2->extents.y2);
- good(newReg);
- return TRUE;
-}
-
-
-/*======================================================================
- * Batch Rectangle Union
- *====================================================================*/
-
-/*-
- *-----------------------------------------------------------------------
- * miRegionAppend --
- *
- * "Append" the rgn rectangles onto the end of dstrgn, maintaining
- * knowledge of YX-banding when it's easy. Otherwise, dstrgn just
- * becomes a non-y-x-banded random collection of rectangles, and not
- * yet a true region. After a sequence of appends, the caller must
- * call miRegionValidate to ensure that a valid region is constructed.
- *
- * Results:
- * TRUE if successful.
- *
- * Side Effects:
- * dstrgn is modified if rgn has rectangles.
- *
- */
-Bool
-miRegionAppend(dstrgn, rgn)
- register RegionPtr dstrgn;
- register RegionPtr rgn;
-{
- int numRects, dnumRects, size;
- BoxPtr new, old;
- Bool prepend;
-
- if (REGION_NAR(rgn))
- return miRegionBreak (dstrgn);
-
- if (!rgn->data && (dstrgn->data == &miEmptyData))
- {
- dstrgn->extents = rgn->extents;
- dstrgn->data = (RegDataPtr)NULL;
- return TRUE;
- }
-
- numRects = REGION_NUM_RECTS(rgn);
- if (!numRects)
- return TRUE;
- prepend = FALSE;
- size = numRects;
- dnumRects = REGION_NUM_RECTS(dstrgn);
- if (!dnumRects && (size < 200))
- size = 200; /* XXX pick numbers out of a hat */
- RECTALLOC(dstrgn, size);
- old = REGION_RECTS(rgn);
- if (!dnumRects)
- dstrgn->extents = rgn->extents;
- else if (dstrgn->extents.x2 > dstrgn->extents.x1)
- {
- register BoxPtr first, last;
-
- first = old;
- last = REGION_BOXPTR(dstrgn) + (dnumRects - 1);
- if ((first->y1 > last->y2) ||
- ((first->y1 == last->y1) && (first->y2 == last->y2) &&
- (first->x1 > last->x2)))
- {
- if (rgn->extents.x1 < dstrgn->extents.x1)
- dstrgn->extents.x1 = rgn->extents.x1;
- if (rgn->extents.x2 > dstrgn->extents.x2)
- dstrgn->extents.x2 = rgn->extents.x2;
- dstrgn->extents.y2 = rgn->extents.y2;
- }
- else
- {
- first = REGION_BOXPTR(dstrgn);
- last = old + (numRects - 1);
- if ((first->y1 > last->y2) ||
- ((first->y1 == last->y1) && (first->y2 == last->y2) &&
- (first->x1 > last->x2)))
- {
- prepend = TRUE;
- if (rgn->extents.x1 < dstrgn->extents.x1)
- dstrgn->extents.x1 = rgn->extents.x1;
- if (rgn->extents.x2 > dstrgn->extents.x2)
- dstrgn->extents.x2 = rgn->extents.x2;
- dstrgn->extents.y1 = rgn->extents.y1;
- }
- else
- dstrgn->extents.x2 = dstrgn->extents.x1;
- }
- }
- if (prepend)
- {
- new = REGION_BOX(dstrgn, numRects);
- if (dnumRects == 1)
- *new = *REGION_BOXPTR(dstrgn);
- else
- memmove((char *)new,(char *)REGION_BOXPTR(dstrgn),
- dnumRects * sizeof(BoxRec));
- new = REGION_BOXPTR(dstrgn);
- }
- else
- new = REGION_BOXPTR(dstrgn) + dnumRects;
- if (numRects == 1)
- *new = *old;
- else
- memmove((char *)new, (char *)old, numRects * sizeof(BoxRec));
- dstrgn->data->numRects += numRects;
- return TRUE;
-}
-
-
-#define ExchangeRects(a, b) \
-{ \
- BoxRec t; \
- t = rects[a]; \
- rects[a] = rects[b]; \
- rects[b] = t; \
-}
-
-static void
-QuickSortRects(
- register BoxRec rects[],
- register int numRects)
-{
- register int y1;
- register int x1;
- register int i, j;
- register BoxPtr r;
-
- /* Always called with numRects > 1 */
-
- do
- {
- if (numRects == 2)
- {
- if (rects[0].y1 > rects[1].y1 ||
- (rects[0].y1 == rects[1].y1 && rects[0].x1 > rects[1].x1))
- ExchangeRects(0, 1);
- return;
- }
-
- /* Choose partition element, stick in location 0 */
- ExchangeRects(0, numRects >> 1);
- y1 = rects[0].y1;
- x1 = rects[0].x1;
-
- /* Partition array */
- i = 0;
- j = numRects;
- do
- {
- r = &(rects[i]);
- do
- {
- r++;
- i++;
- } while (i != numRects &&
- (r->y1 < y1 || (r->y1 == y1 && r->x1 < x1)));
- r = &(rects[j]);
- do
- {
- r--;
- j--;
- } while (y1 < r->y1 || (y1 == r->y1 && x1 < r->x1));
- if (i < j)
- ExchangeRects(i, j);
- } while (i < j);
-
- /* Move partition element back to middle */
- ExchangeRects(0, j);
-
- /* Recurse */
- if (numRects-j-1 > 1)
- QuickSortRects(&rects[j+1], numRects-j-1);
- numRects = j;
- } while (numRects > 1);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miRegionValidate --
- *
- * Take a ``region'' which is a non-y-x-banded random collection of
- * rectangles, and compute a nice region which is the union of all the
- * rectangles.
- *
- * Results:
- * TRUE if successful.
- *
- * Side Effects:
- * The passed-in ``region'' may be modified.
- * pOverlap set to TRUE if any retangles overlapped, else FALSE;
- *
- * Strategy:
- * Step 1. Sort the rectangles into ascending order with primary key y1
- * and secondary key x1.
- *
- * Step 2. Split the rectangles into the minimum number of proper y-x
- * banded regions. This may require horizontally merging
- * rectangles, and vertically coalescing bands. With any luck,
- * this step in an identity tranformation (ala the Box widget),
- * or a coalescing into 1 box (ala Menus).
- *
- * Step 3. Merge the separate regions down to a single region by calling
- * miUnion. Maximize the work each miUnion call does by using
- * a binary merge.
- *
- *-----------------------------------------------------------------------
- */
-
-Bool
-miRegionValidate(badreg, pOverlap)
- RegionPtr badreg;
- Bool *pOverlap;
-{
- /* Descriptor for regions under construction in Step 2. */
- typedef struct {
- RegionRec reg;
- int prevBand;
- int curBand;
- } RegionInfo;
-
- int numRects; /* Original numRects for badreg */
- RegionInfo *ri; /* Array of current regions */
- int numRI; /* Number of entries used in ri */
- int sizeRI; /* Number of entries available in ri */
- int i; /* Index into rects */
- register int j; /* Index into ri */
- register RegionInfo *rit; /* &ri[j] */
- register RegionPtr reg; /* ri[j].reg */
- register BoxPtr box; /* Current box in rects */
- register BoxPtr riBox; /* Last box in ri[j].reg */
- register RegionPtr hreg; /* ri[j_half].reg */
- Bool ret = TRUE;
-
- *pOverlap = FALSE;
- if (!badreg->data)
- {
- good(badreg);
- return TRUE;
- }
- numRects = badreg->data->numRects;
- if (!numRects)
- {
- if (REGION_NAR(badreg))
- return FALSE;
- good(badreg);
- return TRUE;
- }
- if (badreg->extents.x1 < badreg->extents.x2)
- {
- if ((numRects) == 1)
- {
- xfreeData(badreg);
- badreg->data = (RegDataPtr) NULL;
- }
- else
- {
- DOWNSIZE(badreg, numRects);
- }
- good(badreg);
- return TRUE;
- }
-
- /* Step 1: Sort the rects array into ascending (y1, x1) order */
- QuickSortRects(REGION_BOXPTR(badreg), numRects);
-
- /* Step 2: Scatter the sorted array into the minimum number of regions */
-
- /* Set up the first region to be the first rectangle in badreg */
- /* Note that step 2 code will never overflow the ri[0].reg rects array */
- ri = (RegionInfo *) xalloc(4 * sizeof(RegionInfo));
- if (!ri)
- return miRegionBreak (badreg);
- sizeRI = 4;
- numRI = 1;
- ri[0].prevBand = 0;
- ri[0].curBand = 0;
- ri[0].reg = *badreg;
- box = REGION_BOXPTR(&ri[0].reg);
- ri[0].reg.extents = *box;
- ri[0].reg.data->numRects = 1;
-
- /* Now scatter rectangles into the minimum set of valid regions. If the
- next rectangle to be added to a region would force an existing rectangle
- in the region to be split up in order to maintain y-x banding, just
- forget it. Try the next region. If it doesn't fit cleanly into any
- region, make a new one. */
-
- for (i = numRects; --i > 0;)
- {
- box++;
- /* Look for a region to append box to */
- for (j = numRI, rit = ri; --j >= 0; rit++)
- {
- reg = &rit->reg;
- riBox = REGION_END(reg);
-
- if (box->y1 == riBox->y1 && box->y2 == riBox->y2)
- {
- /* box is in same band as riBox. Merge or append it */
- if (box->x1 <= riBox->x2)
- {
- /* Merge it with riBox */
- if (box->x1 < riBox->x2) *pOverlap = TRUE;
- if (box->x2 > riBox->x2) riBox->x2 = box->x2;
- }
- else
- {
- RECTALLOC_BAIL(reg, 1, bail);
- *REGION_TOP(reg) = *box;
- reg->data->numRects++;
- }
- goto NextRect; /* So sue me */
- }
- else if (box->y1 >= riBox->y2)
- {
- /* Put box into new band */
- if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2;
- if (reg->extents.x1 > box->x1) reg->extents.x1 = box->x1;
- Coalesce(reg, rit->prevBand, rit->curBand);
- rit->curBand = reg->data->numRects;
- RECTALLOC_BAIL(reg, 1, bail);
- *REGION_TOP(reg) = *box;
- reg->data->numRects++;
- goto NextRect;
- }
- /* Well, this region was inappropriate. Try the next one. */
- } /* for j */
-
- /* Uh-oh. No regions were appropriate. Create a new one. */
- if (sizeRI == numRI)
- {
- /* Oops, allocate space for new region information */
- sizeRI <<= 1;
- rit = (RegionInfo *) xrealloc(ri, sizeRI * sizeof(RegionInfo));
- if (!rit)
- goto bail;
- ri = rit;
- rit = &ri[numRI];
- }
- numRI++;
- rit->prevBand = 0;
- rit->curBand = 0;
- rit->reg.extents = *box;
- rit->reg.data = (RegDataPtr)NULL;
- if (!miRectAlloc(&rit->reg, (i+numRI) / numRI)) /* MUST force allocation */
- goto bail;
-NextRect: ;
- } /* for i */
-
- /* Make a final pass over each region in order to Coalesce and set
- extents.x2 and extents.y2 */
-
- for (j = numRI, rit = ri; --j >= 0; rit++)
- {
- reg = &rit->reg;
- riBox = REGION_END(reg);
- reg->extents.y2 = riBox->y2;
- if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2;
- Coalesce(reg, rit->prevBand, rit->curBand);
- if (reg->data->numRects == 1) /* keep unions happy below */
- {
- xfreeData(reg);
- reg->data = (RegDataPtr)NULL;
- }
- }
-
- /* Step 3: Union all regions into a single region */
- while (numRI > 1)
- {
- int half = numRI/2;
- for (j = numRI & 1; j < (half + (numRI & 1)); j++)
- {
- reg = &ri[j].reg;
- hreg = &ri[j+half].reg;
- if (!miRegionOp(reg, reg, hreg, miUnionO, TRUE, TRUE, pOverlap))
- ret = FALSE;
- if (hreg->extents.x1 < reg->extents.x1)
- reg->extents.x1 = hreg->extents.x1;
- if (hreg->extents.y1 < reg->extents.y1)
- reg->extents.y1 = hreg->extents.y1;
- if (hreg->extents.x2 > reg->extents.x2)
- reg->extents.x2 = hreg->extents.x2;
- if (hreg->extents.y2 > reg->extents.y2)
- reg->extents.y2 = hreg->extents.y2;
- xfreeData(hreg);
- }
- numRI -= half;
- }
- *badreg = ri[0].reg;
- xfree(ri);
- good(badreg);
- return ret;
-bail:
- for (i = 0; i < numRI; i++)
- xfreeData(&ri[i].reg);
- xfree (ri);
- return miRegionBreak (badreg);
-}
-
-RegionPtr
-miRectsToRegionByBoundary(
- int nrects,
- register xRectangle *prect,
- int ctype,
- int minValue,
- int maxValue)
-{
- register RegionPtr pRgn;
- register RegDataPtr pData;
- register BoxPtr pBox;
- register int i;
- int x1, y1, x2, y2;
-
- pRgn = miRegionCreate(NullBox, 0);
- if (REGION_NAR (pRgn))
- return pRgn;
- if (!nrects)
- return pRgn;
- if (nrects == 1)
- {
- x1 = prect->x < minValue ? minValue : prect->x;
- y1 = prect->y < minValue ? minValue : prect->y;
- if ((x2 = x1 + (int) prect->width) > maxValue)
- x2 = maxValue;
- if ((y2 = y1 + (int) prect->height) > maxValue)
- y2 = maxValue;
- if (x1 != x2 && y1 != y2)
- {
- pRgn->extents.x1 = x1;
- pRgn->extents.y1 = y1;
- pRgn->extents.x2 = x2;
- pRgn->extents.y2 = y2;
- pRgn->data = (RegDataPtr)NULL;
- }
- return pRgn;
- }
- pData = xallocData(nrects);
- if (!pData)
- {
- miRegionBreak (pRgn);
- return pRgn;
- }
- pBox = (BoxPtr) (pData + 1);
- for (i = nrects; --i >= 0; prect++)
- {
- x1 = prect->x < minValue ? minValue : prect->x;
- y1 = prect->y < minValue ? minValue : prect->y;
- if ((x2 = x1 + (int) prect->width) > maxValue)
- x2 = maxValue;
- if ((y2 = y1 + (int) prect->height) > maxValue)
- y2 = maxValue;
- if (x1 != x2 && y1 != y2)
- {
- pBox->x1 = x1;
- pBox->y1 = y1;
- pBox->x2 = x2;
- pBox->y2 = y2;
- pBox->info.type = UpdateRect;
- pBox++;
- }
- }
- if (pBox != (BoxPtr) (pData + 1))
- {
- pData->size = nrects;
- pData->numRects = (int) (pBox - (BoxPtr) (pData + 1));
- pRgn->data = pData;
- if (ctype != CT_YXBANDED)
- {
- Bool overlap; /* result ignored */
- pRgn->extents.x1 = pRgn->extents.x2 = 0;
- miRegionValidate(pRgn, &overlap);
- }
- else
- miSetExtents(pRgn);
- good(pRgn);
- }
- else
- {
- xfree (pData);
- }
- return pRgn;
-}
-
-/*
- * Construct the region from rects using the default values
- * R_MININT and R_MAXINT for boundary check
- */
-RegionPtr
-miRectsToRegion(
- int nrects,
- register xRectangle *prect,
- int ctype)
-{
- return miRectsToRegionByBoundary(nrects, prect, ctype,
- R_MININT, R_MAXINT);
-}
-
-/*======================================================================
- * Region Subtraction
- *====================================================================*/
-
-
-/*-
- *-----------------------------------------------------------------------
- * miSubtractO --
- * Overlapping band subtraction. x1 is the left-most point not yet
- * checked.
- *
- * Results:
- * TRUE if successful.
- *
- * Side Effects:
- * pReg may have rectangles added to it.
- *
- *-----------------------------------------------------------------------
- */
-/*ARGSUSED*/
-static Bool
-miSubtractO (
- register RegionPtr pReg,
- register BoxPtr r1,
- BoxPtr r1End,
- register BoxPtr r2,
- BoxPtr r2End,
- register int y1,
- int y2,
- Bool *pOverlap)
-{
- register BoxPtr pNextRect;
- register int x1;
-
- x1 = r1->x1;
-
- ASSERT(y1<y2);
- ASSERT(r1 != r1End && r2 != r2End);
-
- pNextRect = REGION_TOP(pReg);
-
- do
- {
- if (r2->x2 <= x1)
- {
- /*
- * Subtrahend entirely to left of minuend: go to next subtrahend.
- */
- r2++;
- }
- else if (r2->x1 <= x1)
- {
- /*
- * Subtrahend preceeds minuend: nuke left edge of minuend.
- */
- x1 = r2->x2;
- if (x1 >= r1->x2)
- {
- /*
- * Minuend completely covered: advance to next minuend and
- * reset left fence to edge of new minuend.
- */
- r1++;
- if (r1 != r1End)
- x1 = r1->x1;
- }
- else
- {
- /*
- * Subtrahend now used up since it doesn't extend beyond
- * minuend
- */
- r2++;
- }
- }
- else if (r2->x1 < r1->x2)
- {
- /*
- * Left part of subtrahend covers part of minuend: add uncovered
- * part of minuend to region and skip to next subtrahend.
- */
- RectInfo info = r1->info;
- ASSERT(x1 < r2->x1);
- miRectInfoAdjustForSplit(&info, r1->x1, r1->y1, x1, y1);
- NEWRECT(pReg, pNextRect, x1, y1, r2->x1, y2, info);
-
- x1 = r2->x2;
- if (x1 >= r1->x2)
- {
- /*
- * Minuend used up: advance to new...
- */
- r1++;
- if (r1 != r1End)
- x1 = r1->x1;
- }
- else
- {
- /*
- * Subtrahend used up
- */
- r2++;
- }
- }
- else
- {
- /*
- * Minuend used up: add any remaining piece before advancing.
- */
- if (r1->x2 > x1) {
- RectInfo info = r1->info;
-
- miRectInfoAdjustForSplit(&info, r1->x1, r1->y1, x1, y1);
- NEWRECT(pReg, pNextRect, x1, y1, r1->x2, y2, info);
- }
- r1++;
- if (r1 != r1End)
- x1 = r1->x1;
- }
- } while ((r1 != r1End) && (r2 != r2End));
-
-
- /*
- * Add remaining minuend rectangles to region.
- */
- while (r1 != r1End)
- {
- RectInfo info = r1->info;
-
- ASSERT(x1<r1->x2);
- miRectInfoAdjustForSplit(&info, r1->x1, r1->y1, x1, y1);
- NEWRECT(pReg, pNextRect, x1, y1, r1->x2, y2, info);
- r1++;
- if (r1 != r1End)
- x1 = r1->x1;
- }
- return TRUE;
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miSubtract --
- * Subtract regS from regM and leave the result in regD.
- * S stands for subtrahend, M for minuend and D for difference.
- *
- * Results:
- * TRUE if successful.
- *
- * Side Effects:
- * regD is overwritten.
- *
- *-----------------------------------------------------------------------
- */
-Bool
-miSubtract(regD, regM, regS)
- register RegionPtr regD;
- register RegionPtr regM;
- register RegionPtr regS;
-{
- Bool overlap; /* result ignored */
-
- good(regM);
- good(regS);
- good(regD);
- /* check for trivial rejects */
- if (REGION_NIL(regM) || REGION_NIL(regS) ||
- !EXTENTCHECK(®M->extents, ®S->extents))
- {
- if (REGION_NAR (regS))
- return miRegionBreak (regD);
- return miRegionCopy(regD, regM);
- }
- else if (regM == regS)
- {
- xfreeData(regD);
- regD->extents.x2 = regD->extents.x1;
- regD->extents.y2 = regD->extents.y1;
- regD->data = &miEmptyData;
- return TRUE;
- }
-
- /* Add those rectangles in region 1 that aren't in region 2,
- do yucky subtraction for overlaps, and
- just throw away rectangles in region 2 that aren't in region 1 */
- if (!miRegionOp(regD, regM, regS, miSubtractO, TRUE, FALSE, &overlap))
- return FALSE;
-
- /*
- * Can't alter RegD's extents before we call miRegionOp because
- * it might be one of the source regions and miRegionOp depends
- * on the extents of those regions being unaltered. Besides, this
- * way there's no checking against rectangles that will be nuked
- * due to coalescing, so we have to examine fewer rectangles.
- */
- miSetExtents(regD);
- good(regD);
- return TRUE;
-}
-
-/*======================================================================
- * Region Inversion
- *====================================================================*/
-
-/*-
- *-----------------------------------------------------------------------
- * miInverse --
- * Take a region and a box and return a region that is everything
- * in the box but not in the region. The careful reader will note
- * that this is the same as subtracting the region from the box...
- *
- * Results:
- * TRUE.
- *
- * Side Effects:
- * newReg is overwritten.
- *
- *-----------------------------------------------------------------------
- */
-Bool
-miInverse(newReg, reg1, invRect)
- RegionPtr newReg; /* Destination region */
- RegionPtr reg1; /* Region to invert */
- BoxPtr invRect; /* Bounding box for inversion */
-{
- RegionRec invReg; /* Quick and dirty region made from the
- * bounding box */
- Bool overlap; /* result ignored */
-
- good(reg1);
- good(newReg);
- /* check for trivial rejects */
- if (REGION_NIL(reg1) || !EXTENTCHECK(invRect, ®1->extents))
- {
- if (REGION_NAR(reg1))
- return miRegionBreak (newReg);
- newReg->extents = *invRect;
- xfreeData(newReg);
- newReg->data = (RegDataPtr)NULL;
- return TRUE;
- }
-
- /* Add those rectangles in region 1 that aren't in region 2,
- do yucky subtraction for overlaps, and
- just throw away rectangles in region 2 that aren't in region 1 */
- invReg.extents = *invRect;
- invReg.data = (RegDataPtr)NULL;
- if (!miRegionOp(newReg, &invReg, reg1, miSubtractO, TRUE, FALSE, &overlap))
- return FALSE;
-
- /*
- * Can't alter newReg's extents before we call miRegionOp because
- * it might be one of the source regions and miRegionOp depends
- * on the extents of those regions being unaltered. Besides, this
- * way there's no checking against rectangles that will be nuked
- * due to coalescing, so we have to examine fewer rectangles.
- */
- miSetExtents(newReg);
- good(newReg);
- return TRUE;
-}
-
-/*
- * RectIn(region, rect)
- * This routine takes a pointer to a region and a pointer to a box
- * and determines if the box is outside/inside/partly inside the region.
- *
- * The idea is to travel through the list of rectangles trying to cover the
- * passed box with them. Anytime a piece of the rectangle isn't covered
- * by a band of rectangles, partOut is set TRUE. Any time a rectangle in
- * the region covers part of the box, partIn is set TRUE. The process ends
- * when either the box has been completely covered (we reached a band that
- * doesn't overlap the box, partIn is TRUE and partOut is false), the
- * box has been partially covered (partIn == partOut == TRUE -- because of
- * the banding, the first time this is true we know the box is only
- * partially in the region) or is outside the region (we reached a band
- * that doesn't overlap the box at all and partIn is false)
- */
-
-int
-miRectIn(region, prect)
- register RegionPtr region;
- register BoxPtr prect;
-{
- register int x;
- register int y;
- register BoxPtr pbox;
- register BoxPtr pboxEnd;
- int partIn, partOut;
- int numRects;
-
- good(region);
- numRects = REGION_NUM_RECTS(region);
- /* useful optimization */
- if (!numRects || !EXTENTCHECK(®ion->extents, prect))
- return(rgnOUT);
-
- if (numRects == 1)
- {
- /* We know that it must be rgnIN or rgnPART */
- if (SUBSUMES(®ion->extents, prect))
- return(rgnIN);
- else
- return(rgnPART);
- }
-
- partOut = FALSE;
- partIn = FALSE;
-
- /* (x,y) starts at upper left of rect, moving to the right and down */
- x = prect->x1;
- y = prect->y1;
-
- /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */
- for (pbox = REGION_BOXPTR(region), pboxEnd = pbox + numRects;
- pbox != pboxEnd;
- pbox++)
- {
-
- if (pbox->y2 <= y)
- continue; /* getting up to speed or skipping remainder of band */
-
- if (pbox->y1 > y)
- {
- partOut = TRUE; /* missed part of rectangle above */
- if (partIn || (pbox->y1 >= prect->y2))
- break;
- y = pbox->y1; /* x guaranteed to be == prect->x1 */
- }
-
- if (pbox->x2 <= x)
- continue; /* not far enough over yet */
-
- if (pbox->x1 > x)
- {
- partOut = TRUE; /* missed part of rectangle to left */
- if (partIn)
- break;
- }
-
- if (pbox->x1 < prect->x2)
- {
- partIn = TRUE; /* definitely overlap */
- if (partOut)
- break;
- }
-
- if (pbox->x2 >= prect->x2)
- {
- y = pbox->y2; /* finished with this band */
- if (y >= prect->y2)
- break;
- x = prect->x1; /* reset x out to left again */
- }
- else
- {
- /*
- * Because boxes in a band are maximal width, if the first box
- * to overlap the rectangle doesn't completely cover it in that
- * band, the rectangle must be partially out, since some of it
- * will be uncovered in that band. partIn will have been set true
- * by now...
- */
- partOut = TRUE;
- break;
- }
- }
-
- return(partIn ? ((y < prect->y2) ? rgnPART : rgnIN) : rgnOUT);
-}
-
-/* TranslateRegion(pReg, x, y)
- translates in place
-*/
-
-/*
- * XXX: This function is not written as cleanly as it could be (it
- * uses the same rectangle clipping code twice and uses bitwise
- * operators to detect the different region translation cases).
- */
-
-void
-miTranslateRegionByBoundary(
- register RegionPtr pReg,
- register int x,
- register int y,
- int minValue,
- int maxValue)
-{
- int x1, x2, y1, y2;
- register int nbox;
- register BoxPtr pbox;
-
- good(pReg);
- pReg->extents.x1 = x1 = pReg->extents.x1 + x;
- pReg->extents.y1 = y1 = pReg->extents.y1 + y;
- pReg->extents.x2 = x2 = pReg->extents.x2 + x;
- pReg->extents.y2 = y2 = pReg->extents.y2 + y;
- if (((x1 - minValue)|(y1 - minValue)|(maxValue - x2)|(maxValue - y2)) >= 0)
- {
- if (pReg->data && (nbox = pReg->data->numRects))
- {
- for (pbox = REGION_BOXPTR(pReg); nbox--; pbox++)
- {
- pbox->x1 += x;
- pbox->y1 += y;
- pbox->x2 += x;
- pbox->y2 += y;
- }
- }
- return;
- }
- if (((x2 - minValue)|(y2 - minValue)|(maxValue - x1)|(maxValue - y1)) <= 0)
- {
- pReg->extents.x2 = pReg->extents.x1;
- pReg->extents.y2 = pReg->extents.y1;
- xfreeData(pReg);
- pReg->data = &miEmptyData;
- return;
- }
- if (x1 < minValue)
- pReg->extents.x1 = minValue;
- else if (x2 > maxValue)
- pReg->extents.x2 = maxValue;
- if (y1 < minValue)
- pReg->extents.y1 = minValue;
- else if (y2 > maxValue)
- pReg->extents.y2 = maxValue;
- if (pReg->data && (nbox = pReg->data->numRects))
- {
- register BoxPtr pboxout;
-
- for (pboxout = pbox = REGION_BOXPTR(pReg); nbox--; pbox++)
- {
- pboxout->x1 = x1 = pbox->x1 + x;
- pboxout->y1 = y1 = pbox->y1 + y;
- pboxout->x2 = x2 = pbox->x2 + x;
- pboxout->y2 = y2 = pbox->y2 + y;
- if (((x2 - minValue)|(y2 - minValue)|
- (maxValue - x1)|(maxValue - y1)) <= 0)
- {
- pReg->data->numRects--;
- continue;
- }
- if (x1 < minValue)
- pboxout->x1 = minValue;
- else if (x2 > maxValue)
- pboxout->x2 = maxValue;
- if (y1 < minValue)
- pboxout->y1 = minValue;
- else if (y2 > maxValue)
- pboxout->y2 = maxValue;
- pboxout++;
- }
- if (pboxout != pbox)
- {
- if (pReg->data->numRects == 1)
- {
- pReg->extents = *REGION_BOXPTR(pReg);
- xfreeData(pReg);
- pReg->data = (RegDataPtr)NULL;
- }
- else
- miSetExtents(pReg);
- }
- }
-}
-
-/*
- * Translate the region and use the default values which are
- * R_MININT, R_MAXINT for boundary check
- */
-
-void
-miTranslateRegion(
- register RegionPtr pReg,
- register int x,
- register int y)
-{
- miTranslateRegionByBoundary(pReg, x, y, R_MININT, R_MAXINT);
-}
-
-
-Bool
-miRegionDataCopy(
- register RegionPtr dst,
- register RegionPtr src)
-{
- good(dst);
- good(src);
- if (dst->data)
- return TRUE;
- if (dst == src)
- return TRUE;
- if (!src->data || !src->data->size)
- {
- xfreeData(dst);
- dst->data = (RegDataPtr)NULL;
- return TRUE;
- }
- if (!dst->data || (dst->data->size < src->data->numRects))
- {
- xfreeData(dst);
- dst->data = xallocData(src->data->numRects);
- if (!dst->data)
- return miRegionBreak (dst);
- }
- dst->data->size = src->data->size;
- dst->data->numRects = src->data->numRects;
- return TRUE;
-}
-
-void
-miRegionReset(pReg, pBox)
- RegionPtr pReg;
- BoxPtr pBox;
-{
- good(pReg);
- ASSERT(pBox->x1<=pBox->x2);
- ASSERT(pBox->y1<=pBox->y2);
- pReg->extents = *pBox;
- xfreeData(pReg);
- pReg->data = (RegDataPtr)NULL;
-}
-
-Bool
-miPointInRegion(pReg, x, y, box)
- register RegionPtr pReg;
- register int x, y;
- BoxPtr box; /* "return" value */
-{
- register BoxPtr pbox, pboxEnd;
- int numRects;
-
- good(pReg);
- numRects = REGION_NUM_RECTS(pReg);
- if (!numRects || !INBOX(&pReg->extents, x, y))
- return(FALSE);
- if (numRects == 1)
- {
- *box = pReg->extents;
- return(TRUE);
- }
- for (pbox = REGION_BOXPTR(pReg), pboxEnd = pbox + numRects;
- pbox != pboxEnd;
- pbox++)
- {
- if (y >= pbox->y2)
- continue; /* not there yet */
- if ((y < pbox->y1) || (x < pbox->x1))
- break; /* missed it */
- if (x >= pbox->x2)
- continue; /* not there yet */
- *box = *pbox;
- return(TRUE);
- }
- return(FALSE);
-}
-
-Bool
-miRegionNotEmpty(pReg)
- RegionPtr pReg;
-{
- good(pReg);
- return(!REGION_NIL(pReg));
-}
-
-Bool
-miRegionBroken(RegionPtr pReg)
-{
- good(pReg);
- return (REGION_NAR(pReg));
-}
-
-void
-miRegionEmpty(pReg)
- RegionPtr pReg;
-{
- good(pReg);
- xfreeData(pReg);
- pReg->extents.x2 = pReg->extents.x1;
- pReg->extents.y2 = pReg->extents.y1;
- pReg->data = &miEmptyData;
-}
-
-BoxPtr
-miRegionExtents(pReg)
- RegionPtr pReg;
-{
- good(pReg);
- return(&pReg->extents);
-}
-
-#define ExchangeSpans(a, b) \
-{ \
- DDXPointRec tpt; \
- register int tw; \
- \
- tpt = spans[a]; spans[a] = spans[b]; spans[b] = tpt; \
- tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \
-}
-
-/* ||| I should apply the merge sort code to rectangle sorting above, and see
- if mapping time can be improved. But right now I've been at work 12 hours,
- so forget it.
-*/
-
-static void QuickSortSpans(
- register DDXPointRec spans[],
- register int widths[],
- register int numSpans)
-{
- register int y;
- register int i, j, m;
- register DDXPointPtr r;
-
- /* Always called with numSpans > 1 */
- /* Sorts only by y, doesn't bother to sort by x */
-
- do
- {
- if (numSpans < 9)
- {
- /* Do insertion sort */
- register int yprev;
-
- yprev = spans[0].y;
- i = 1;
- do
- { /* while i != numSpans */
- y = spans[i].y;
- if (yprev > y)
- {
- /* spans[i] is out of order. Move into proper location. */
- DDXPointRec tpt;
- int tw, k;
-
- for (j = 0; y >= spans[j].y; j++) {}
- tpt = spans[i];
- tw = widths[i];
- for (k = i; k != j; k--)
- {
- spans[k] = spans[k-1];
- widths[k] = widths[k-1];
- }
- spans[j] = tpt;
- widths[j] = tw;
- y = spans[i].y;
- } /* if out of order */
- yprev = y;
- i++;
- } while (i != numSpans);
- return;
- }
-
- /* Choose partition element, stick in location 0 */
- m = numSpans / 2;
- if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
- if (spans[m].y > spans[numSpans-1].y) ExchangeSpans(m, numSpans-1);
- if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
- y = spans[0].y;
-
- /* Partition array */
- i = 0;
- j = numSpans;
- do
- {
- r = &(spans[i]);
- do
- {
- r++;
- i++;
- } while (i != numSpans && r->y < y);
- r = &(spans[j]);
- do
- {
- r--;
- j--;
- } while (y < r->y);
- if (i < j)
- ExchangeSpans(i, j);
- } while (i < j);
-
- /* Move partition element back to middle */
- ExchangeSpans(0, j);
-
- /* Recurse */
- if (numSpans-j-1 > 1)
- QuickSortSpans(&spans[j+1], &widths[j+1], numSpans-j-1);
- numSpans = j;
- } while (numSpans > 1);
-}
-
-#define NextBand() \
-{ \
- clipy1 = pboxBandStart->y1; \
- clipy2 = pboxBandStart->y2; \
- pboxBandEnd = pboxBandStart + 1; \
- while (pboxBandEnd != pboxLast && pboxBandEnd->y1 == clipy1) { \
- pboxBandEnd++; \
- } \
- for (; ppt != pptLast && ppt->y < clipy1; ppt++, pwidth++) {} \
-}
-
-/*
- Clip a list of scanlines to a region. The caller has allocated the
- space. FSorted is non-zero if the scanline origins are in ascending
- order.
- returns the number of new, clipped scanlines.
-*/
-
-int
-miClipSpans(
- RegionPtr prgnDst,
- register DDXPointPtr ppt,
- register int *pwidth,
- int nspans,
- register DDXPointPtr pptNew,
- int *pwidthNew,
- int fSorted)
-{
- register DDXPointPtr pptLast;
- int *pwidthNewStart; /* the vengeance of Xerox! */
- register int y, x1, x2;
- register int numRects;
-
- good(prgnDst);
- pptLast = ppt + nspans;
- pwidthNewStart = pwidthNew;
-
- if (!prgnDst->data)
- {
- /* Do special fast code with clip boundaries in registers(?) */
- /* It doesn't pay much to make use of fSorted in this case,
- so we lump everything together. */
-
- register int clipx1, clipx2, clipy1, clipy2;
-
- clipx1 = prgnDst->extents.x1;
- clipy1 = prgnDst->extents.y1;
- clipx2 = prgnDst->extents.x2;
- clipy2 = prgnDst->extents.y2;
-
- for (; ppt != pptLast; ppt++, pwidth++)
- {
- y = ppt->y;
- x1 = ppt->x;
- if (clipy1 <= y && y < clipy2)
- {
- x2 = x1 + *pwidth;
- if (x1 < clipx1) x1 = clipx1;
- if (x2 > clipx2) x2 = clipx2;
- if (x1 < x2)
- {
- /* part of span in clip rectangle */
- pptNew->x = x1;
- pptNew->y = y;
- *pwidthNew = x2 - x1;
- pptNew++;
- pwidthNew++;
- }
- }
- } /* end for */
-
- }
- else if ((numRects = prgnDst->data->numRects))
- {
- /* Have to clip against many boxes */
- BoxPtr pboxBandStart, pboxBandEnd;
- register BoxPtr pbox;
- register BoxPtr pboxLast;
- register int clipy1, clipy2;
-
- /* In this case, taking advantage of sorted spans gains more than
- the sorting costs. */
- if ((! fSorted) && (nspans > 1))
- QuickSortSpans(ppt, pwidth, nspans);
-
- pboxBandStart = REGION_BOXPTR(prgnDst);
- pboxLast = pboxBandStart + numRects;
-
- NextBand();
-
- for (; ppt != pptLast; )
- {
- y = ppt->y;
- if (y < clipy2)
- {
- /* span is in the current band */
- pbox = pboxBandStart;
- x1 = ppt->x;
- x2 = x1 + *pwidth;
- do
- { /* For each box in band */
- register int newx1, newx2;
-
- newx1 = x1;
- newx2 = x2;
- if (newx1 < pbox->x1) newx1 = pbox->x1;
- if (newx2 > pbox->x2) newx2 = pbox->x2;
- if (newx1 < newx2)
- {
- /* Part of span in clip rectangle */
- pptNew->x = newx1;
- pptNew->y = y;
- *pwidthNew = newx2 - newx1;
- pptNew++;
- pwidthNew++;
- }
- pbox++;
- } while (pbox != pboxBandEnd);
- ppt++;
- pwidth++;
- }
- else
- {
- /* Move to next band, adjust ppt as needed */
- pboxBandStart = pboxBandEnd;
- if (pboxBandStart == pboxLast)
- break; /* We're completely done */
- NextBand();
- }
- }
- }
- return (int) (pwidthNew - pwidthNewStart);
-}
-
-/* find the band in a region with the most rectangles */
-int
-miFindMaxBand(prgn)
- RegionPtr prgn;
-{
- register int nbox;
- register BoxPtr pbox;
- register int nThisBand;
- register int nMaxBand = 0;
- int yThisBand;
-
- good(prgn);
- nbox = REGION_NUM_RECTS(prgn);
- pbox = REGION_RECTS(prgn);
-
- while(nbox > 0)
- {
- yThisBand = pbox->y1;
- nThisBand = 0;
- while((nbox > 0) && (pbox->y1 == yThisBand))
- {
- nbox--;
- pbox++;
- nThisBand++;
- }
- if (nThisBand > nMaxBand)
- nMaxBand = nThisBand;
- }
- return (nMaxBand);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * miApplyRect --
- *
- * This is a simple helper function for use with the common case of
- * (newreg = oldreg (op) newrect) where (op) is one of miUnion,
- * miSubtract, miIntersect.
- *
- * Results:
- * TRUE on success, FALSE otherwise.
- *
- * Side effects:
- * Modifies newReg.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-miApplyRect(RegionPtr newReg, RegionPtr reg, BoxPtr rect,
- Bool (*op) (RegionPtr, RegionPtr, RegionPtr))
-{
- RegionRec topReg;
-
- good(reg);
-
- ASSERT(RECTINFO_ISVALID(rect->info));
-
- if (rect->x2 <= rect->x1 || rect->y2 <= rect->y1) {
- rect->x2 = rect->x1 = rect->y2 = rect->y1 = 0;
- topReg.data = &miEmptyData;
- } else {
- topReg.data = NULL;
- }
-
- topReg.extents = *rect;
-
- return (op)(newReg, reg, &topReg);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * miRegionArea --
- *
- * Returns the total actual area covered by all the rectangles in the
- * region. Note that this is not the same as the area of the bounding
- * box, obviously.
- *
- * XXX *could* calculate this iteratively and try to keep it up to date.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-miRegionArea(RegionPtr reg)
-{
- int i, area = 0;
-
- for (i = 0; i < REGION_NUM_RECTS(reg); i++) {
- BoxPtr rect = ®ION_RECTS(reg)[i];
- ASSERT(rect);
- area += (rect->x2 - rect->x1) * (rect->y2 - rect->y1);
- }
-
- return area;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * miRegionMatch --
- *
- * Sets newReg to be a region containing all rects in reg for which
- * match(rect) returns TRUE.
- *
- * Results:
- * Returns TRUE if there were any matches.
- *
- * Side effects:
- * Modifies newReg.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-miRegionMatch(RegionPtr newReg, RegionPtr reg,
- miRegionMatchFunc match, uintptr_t userData)
-{
- int i;
- Bool ret = FALSE;
- RegionRec tmp;
-
- /*
- * Use a tmp region in case newReg and reg point to the same region.
- */
- miRegionInit(&tmp, NullBox, 0);
-
- for (i = 0; i < REGION_NUM_RECTS(reg); i++) {
- BoxPtr rect = REGION_RECTS(reg) + i;
- if (match(rect, userData)) {
- miApplyRect(&tmp, &tmp, rect, miUnion);
- ret = TRUE;
- }
- }
-
- miRegionCopy(newReg, &tmp);
-
- miRegionUninit(&tmp);
-
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * miIsRegionVoid --
- *
- * Checks if the region passes the REGION_NIL test. If it doesn't
- * pass, checks if the region's extents rectangle has 0 size.
- *
- * Results:
- * TRUE if the region is void, FALSE otherwise.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-miIsRegionVoid(RegionPtr reg) // IN
-{
- return REGION_NIL(reg)
- || ( reg->data == NULL
- && reg->extents.x1 == reg->extents.x2
- && reg->extents.y1 == reg->extents.y2);
-}
SUBDIRS += resolutionSet
endif
SUBDIRS += timeSync
-if ENABLE_UNITY
- SUBDIRS += unity
-endif
SUBDIRS += vix
SUBDIRS += vmbackup
+++ /dev/null
-################################################################################
-### Copyright 2010 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
-################################################################################
-
-plugindir = @VMUSR_PLUGIN_INSTALLDIR@
-plugin_LTLIBRARIES = libunity.la
-
-CFLAGS += -Wno-unused
-
-libunity_la_CPPFLAGS =
-libunity_la_CPPFLAGS += @GTK_CPPFLAGS@
-libunity_la_CPPFLAGS += @GTKMM_CPPFLAGS@
-libunity_la_CPPFLAGS += @GIO_CPPFLAGS@
-libunity_la_CPPFLAGS += @LIBPNG_CPPFLAGS@
-libunity_la_CPPFLAGS += @URIPARSER_CPPFLAGS@
-libunity_la_CPPFLAGS += @PLUGIN_CPPFLAGS@
-libunity_la_CPPFLAGS += -I$(top_srcdir)/services/plugins/unity/ghIntegration
-libunity_la_CPPFLAGS += -I$(top_srcdir)/services/plugins/unity/unitylib
-libunity_la_CPPFLAGS += -I$(top_srcdir)/services/plugins/unity/unityWindowTracker
-libunity_la_CPPFLAGS += -I$(top_builddir)/include
-
-libunity_la_LDFLAGS =
-libunity_la_LDFLAGS += @PLUGIN_LDFLAGS@
-
-libunity_la_LIBADD =
-libunity_la_LIBADD += @COMMON_XLIBS@
-libunity_la_LIBADD += @XCOMPOSITE_LIBS@
-libunity_la_LIBADD += @GTK_LIBS@
-libunity_la_LIBADD += @GTKMM_LIBS@
-libunity_la_LIBADD += @GIO_LIBS@
-libunity_la_LIBADD += @LIBPNG_LIBS@
-libunity_la_LIBADD += @URIPARSER_LIBS@
-libunity_la_LIBADD += @VMTOOLS_LIBS@
-libunity_la_LIBADD += $(top_builddir)/lib/appUtil/libAppUtil.la
-libunity_la_LIBADD += $(top_builddir)/lib/image/libImage.la
-libunity_la_LIBADD += $(top_builddir)/lib/raster/libRaster.la
-libunity_la_LIBADD += $(top_builddir)/lib/region/libRegion.la
-libunity_la_LIBADD += $(top_builddir)/lib/xdg/libXdg.la
-
-libunity_la_SOURCES =
-
-libunity_la_SOURCES += toolsPlugin.cpp
-libunity_la_SOURCES += unityPlugin.cpp
-libunity_la_SOURCES += unityPluginEntry.cpp
-libunity_la_SOURCES += unityPlugin.h
-libunity_la_SOURCES += unityPluginPosix.h
-libunity_la_SOURCES += unityPluginPosix.cpp
-libunity_la_SOURCES += ghiTclo.h
-libunity_la_SOURCES += ghiTclo.cpp
-libunity_la_SOURCES += unityTclo.h
-libunity_la_SOURCES += unityTclo.cpp
-
-libunity_la_SOURCES += ghIntegration/ghIntegration.cpp
-libunity_la_SOURCES += ghIntegration/ghIntegrationInt.h
-libunity_la_SOURCES += ghIntegration/icon.cc
-libunity_la_SOURCES += ghIntegration/platform.cc
-libunity_la_SOURCES += ghIntegration/pseudoAppMgr.cc
-
-libunity_la_SOURCES += unitylib/unity.c
-libunity_la_SOURCES += unitylib/unityInt.h
-libunity_la_SOURCES += unitylib/unityPlatform.h
-libunity_la_SOURCES += unitylib/debug.c
-libunity_la_SOURCES += unitylib/event.cc
-libunity_la_SOURCES += unitylib/settings.cc
-libunity_la_SOURCES += unitylib/util.cc
-libunity_la_SOURCES += unitylib/window.cc
-libunity_la_SOURCES += unitylib/windowPathFactory.cc
-libunity_la_SOURCES += unitylib/x11Platform.cc
-libunity_la_SOURCES += unitylib/x11Platform.h
-
-libunity_la_SOURCES += unityWindowTracker/unityWindowTracker.c
-
-RPCGEN_SRCS =
-RPCGEN_SRCS += ghiGetBinaryHandlers_xdr.c
-RPCGEN_SRCS += ghiGetExecInfoHash_xdr.c
-RPCGEN_SRCS += ghiProtocolHandler_xdr.c
-RPCGEN_SRCS += ghiStartMenu_xdr.c
-RPCGEN_SRCS += ghiShellAction_xdr.c
-RPCGEN_SRCS += ghiTrayIcon_xdr.c
-RPCGEN_SRCS += ghiSetFocusedWindow_xdr.c
-RPCGEN_SRCS += ghiSetGuestHandler_xdr.c
-RPCGEN_SRCS += ghiSetOutlookTempFolder_xdr.c
-RPCGEN_SRCS += unityActive_xdr.c
-RPCGEN_SRCS += unity_xdr.c
-
-RPCGEN_HDRS =
-RPCGEN_HDRS += ghiGetBinaryHandlers.h
-RPCGEN_HDRS += ghiGetExecInfoHash.h
-RPCGEN_HDRS += ghiProtocolHandler.h
-RPCGEN_HDRS += ghiStartMenu.h
-RPCGEN_HDRS += ghiShellAction.h
-RPCGEN_HDRS += ghiTrayIcon.h
-RPCGEN_HDRS += ghiSetFocusedWindow.h
-RPCGEN_HDRS += ghiSetGuestHandler.h
-RPCGEN_HDRS += ghiSetOutlookTempFolder.h
-RPCGEN_HDRS += unityActive.h
-RPCGEN_HDRS += unity.h
-
-BUILT_SOURCES =
-BUILT_SOURCES += $(RPCGEN_HDRS)
-BUILT_SOURCES += $(RPCGEN_SRCS)
-
-CLEANFILES =
-CLEANFILES += $(BUILT_SOURCES)
-
-libunity_la_SOURCES += $(RPCGEN_SRCS)
-
-## `make clean` should also remove the copied headers.
-clean-local:
- rm -rf $(top_builddir)/lib/include/guestrpc
- if [ $(top_builddir) != $(top_srcdir) ]; then \
- rm -f *.x; \
- rm -f ghiCommonDefines.h; \
- fi
-
-ghiGetBinaryHandlers.h: ghiGetBinaryHandlers.x
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiGetBinaryHandlers.x $@ \
- services/plugins/unity/ghiCommonDefines.h
-
-ghiGetBinaryHandlers_xdr.c: ghiGetBinaryHandlers.x ghiGetBinaryHandlers.h
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiGetBinaryHandlers.x $@
-
-ghiGetExecInfoHash.h: ghiGetExecInfoHash.x
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiGetExecInfoHash.x $@ \
- services/plugins/unity/ghiCommonDefines.h
-
-ghiGetExecInfoHash_xdr.c: ghiGetExecInfoHash.x ghiGetExecInfoHash.h
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiGetExecInfoHash.x $@
-
-ghiProtocolHandler.h: ghiProtocolHandler.x
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiProtocolHandler.x $@ \
- services/plugins/unity/ghiCommonDefines.h
-
-ghiProtocolHandler_xdr.c: ghiProtocolHandler.x ghiProtocolHandler.h
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiProtocolHandler.x $@
-
-ghiStartMenu.h: ghiStartMenu.x
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiStartMenu.x $@ \
- services/plugins/unity/ghiCommonDefines.h
-
-ghiStartMenu_xdr.c: ghiStartMenu.x ghiStartMenu.h
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiStartMenu.x $@
-
-ghiShellAction.h: ghiShellAction.x
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiShellAction.x $@ \
- services/plugins/unity/ghiCommonDefines.h
-
-ghiShellAction_xdr.c: ghiShellAction.x ghiShellAction.h
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiShellAction.x $@
-
-ghiTrayIcon.h: ghiTrayIcon.x
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiTrayIcon.x $@ \
- services/plugins/unity/ghiCommonDefines.h
-
-ghiTrayIcon_xdr.c: ghiTrayIcon.x ghiTrayIcon.h
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiTrayIcon.x $@
-
-ghiSetFocusedWindow.h: ghiSetFocusedWindow.x
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiSetFocusedWindow.x $@ \
- services/plugins/unity/ghiCommonDefines.h
-
-ghiSetFocusedWindow_xdr.c: ghiSetFocusedWindow.x ghiSetFocusedWindow.h
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiSetFocusedWindow.x $@
-
-ghiSetGuestHandler.h: ghiSetGuestHandler.x
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiSetGuestHandler.x $@ \
- services/plugins/unity/ghiCommonDefines.h
-
-ghiSetGuestHandler_xdr.c: ghiSetGuestHandler.x ghiSetGuestHandler.h
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiSetGuestHandler.x $@
-
-ghiSetOutlookTempFolder.h: ghiSetOutlookTempFolder.x
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiSetOutlookTempFolder.x $@ \
- services/plugins/unity/ghiCommonDefines.h
-
-ghiSetOutlookTempFolder_xdr.c: ghiSetOutlookTempFolder.x ghiSetOutlookTempFolder.h
- @RPCGEN_WRAPPER@ services/plugins/unity/ghiSetOutlookTempFolder.x $@
-
-unityActive.h: unityActive.x
- @RPCGEN_WRAPPER@ services/plugins/unity/unityActive.x $@
-
-unityActive_xdr.c: unityActive.x unityActive.h
- @RPCGEN_WRAPPER@ services/plugins/unity/unityActive.x $@
-
-unity.h: unity.x
- @RPCGEN_WRAPPER@ services/plugins/unity/unity.x $@
-
-unity_xdr.c: unity.x unity.h
- @RPCGEN_WRAPPER@ services/plugins/unity/unity.x $@
-
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * ghIntegration.cpp --
- *
- * Guest-host integration functions.
- */
-
-#include "appUtil.h"
-#include "ghIntegration.h"
-#include "ghIntegrationInt.h"
-
-extern "C" {
-#include "vmware.h"
-#include "debug.h"
-#include "guest_msg_def.h"
-#include "str.h"
-#include "strutil.h"
-#include "util.h"
-};
-
-using vmware::tools::NotifyIconCallback;
-
-// The pointer to the platform-specific global state.
-static GHIPlatform *ghiPlatformData = NULL;
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHI_IsSupported --
- *
- * Determine whether this guest supports guest-host integration.
- *
- * Results:
- * TRUE if the guest supports guest-host integration
- * FALSE otherwise
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHI_IsSupported(void)
-{
- return GHIPlatformIsSupported();
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GHI_Init --
- *
- * One time initialization stuff.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May register with the tools poll loop.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-GHI_Init(GMainLoop *mainLoop, // IN
- const char **envp, // IN
- GHIHostCallbacks hostCallbacks) // IN
-{
- Debug("%s: Enter.\n", __FUNCTION__);
-
- // Call the platform-specific initialization function.
- ghiPlatformData = GHIPlatformInit(mainLoop, envp, hostCallbacks);
- if (!ghiPlatformData) {
- // TODO: We should report this failure to the caller.
- Debug("%s: GHIPlatformInit returned NULL pointer!\n", __FUNCTION__);
- }
-
-#ifdef _WIN32
- AppUtil_BuildGlobalApplicationList();
-#endif // _WIN32
-
- Debug("%s: Exit.\n", __FUNCTION__);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GHI_Cleanup --
- *
- * One time cleanup.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-GHI_Cleanup(void)
-{
- if (NULL != ghiPlatformData) {
- GHIPlatformCleanup(ghiPlatformData);
- }
- ghiPlatformData = NULL;
-}
-
-
-#ifndef _WIN32
-/*
- ******************************************************************************
- * GHIX11_FindDesktopUriByExec -- */ /**
- *
- * Given an executable path, attempt to generate an "execUri" associated with a
- * corresponding .desktop file.
- *
- * @note Returned pointer belongs to the GHI module. Caller must not free it.
- *
- * @param[in] execPath Input binary path. May be absolute or relative.
- *
- * @return Pointer to a URI string on success, NULL on failure.
- *
- ******************************************************************************
- */
-
-const char *
-GHIX11_FindDesktopUriByExec(const char *exec)
-{
- ASSERT(ghiPlatformData);
-
- return GHIX11FindDesktopUriByExec(ghiPlatformData, exec);
-}
-#endif // ifndef _WIN32
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHI_GetBinaryInfo --
- *
- * Get binary information. Returns the 'friendly name' of the application, and
- * a list of various sized icons (depending on the icons provided by the app).
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHI_GetBinaryInfo(const char *pathUriUtf8, // IN: full path to the binary file
- std::string &friendlyName, // OUT: friendly (long) name
- std::list<GHIBinaryIconInfo> &iconList) // OUT: List of app icons
-{
- return GHIPlatformGetBinaryInfo(ghiPlatformData, pathUriUtf8, friendlyName, iconList);
-}
-
-
-#if !defined(OPEN_VM_TOOLS) && !defined(__FreeBSD__) && !defined(sun) && !defined(__APPLE__)
-/*
- *----------------------------------------------------------------------------
- *
- * GHI_GetBinaryHandlers --
- *
- * Get filetypes (extensions) and URL Protocols supported by the application.
- *
- * Results:
- * A list of the filetypes (and protocols) handled by the application.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-const FileTypeList&
-GHI_GetBinaryHandlers(const char *pathUtf8) // IN: full path to the executable
-{
- return GHIPlatformGetBinaryHandlers(ghiPlatformData, pathUtf8);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHI_OpenStartMenuTree --
- *
- * Get the start menu sub-tree for a given item, save it in the array so
- * it can be accessed later when the VMX needs to iterate over the items.
- * Return the count of the items in the sub-tree and a handle to this
- * sub-tree. The handle will be used by the VMX to iterate over the sub-items.
- *
- * Results:
- * TRUE if everything is successful
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool GHI_OpenStartMenuTree(const char *rootUtf8, // IN:
- uint32 flags, // IN:
- uint32 &handle, // OUT: handle for menu
- uint32 &numItems) // OUT: number of items in menu
-{
- return GHIPlatformOpenStartMenuTree(ghiPlatformData, rootUtf8, flags, handle, numItems);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHI_GetStartMenuItem --
- *
- * Get the start menu item at the given index for the tree with a given handle.
- * If there's no item at the given index, return FALSE.
- *
- * Results:
- * TRUE if the item was found.
- * FALSE otherwise (i.e. if the VMX provides a wrong handle or if there's
- no items left).
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHI_GetStartMenuItem(uint32 handle, // IN: tree handle
- uint32 itemIndex, // IN: the index of the item in the tree
- Bool &isSubmenu, // OUT: True if this item is a submenu
- utf::string &menuPath, // OUT: Path to the submenu (if this item is a submenu)
- utf::string &itemPathURI, // OUT: URI for the item (empty if this is a submenu)
- utf::string &itemName) // OUT: The name/label for the item
-{
- return GHIPlatformGetStartMenuItem(ghiPlatformData, handle, itemIndex,
- isSubmenu, menuPath, itemPathURI, itemName);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHI_CloseStartMenuTree --
- *
- * Free all memory associated with this start menu tree and cleanup.
- *
- * Results:
- * TRUE if the handle is valid
- * FALSE otherwise
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHI_CloseStartMenuTree(uint32 handle) // IN: handle to the tree to be closed
-{
- return GHIPlatformCloseStartMenuTree(ghiPlatformData, handle);
-}
-#endif // !OPEN_VM_TOOLS && !__FreeBSD__ && !sun && !__APPLE__
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHI_ShellOpen --
- *
- * Open the specified file with the default shell handler (ShellExecute).
- * Note that the file path may be either a URI (originated with
- * Tools >= NNNNN), or a regular path (originated with Tools < NNNNN).
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHI_ShellOpen(const char *fileURIUtf8) // IN
-{
- return GHIPlatformShellOpen(ghiPlatformData, fileURIUtf8);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHI_ShellAction --
- *
- * The action command has three arguments:
- * an action URI, a target URI, and an array of location URIs.
- * Action URIs are in the form: "x-vmware-action://<verb>", where <verb> is
- * the name of a specific action to perform.
- * The target URI is a guest-specific URI that was previously given to the
- * host (usually a path to an application to run). Note that this may be
- * either a URI (new Tools) or a regular path (old Tools).
- * The locations can be files or URLs. Files are typically specified as
- * HGFS shared folder locations (see below), but can potentially use the
- * "file://<path>" URIs as well.
- * Each guest can specify the features it supports using capability flags:
- *
- * Capability Description
- *
- * GHI_CAP_CMD_SHELL_ACTION Guest allows 'ghi.guest.shell.action'.
- * This encompasses this entire command
- * and the rest of the capabilities.
- *
- * GHI_CAP_SHELL_ACTION_BROWSE Guest supports the 'browse' action verb,
- * used to open a file browser window with
- * a given set of locations.
- *
- * GHI_CAP_SHELL_ACTION_RUN Guest supports the 'run' action verb,
- * used for running applications as well
- * as opening file or URL locations.
- *
- * GHI_CAP_SHELL_LOCATION_HGFS Guest supports HGFS share location URIs:
- * "x-vmware-share://<path>", where <path>
- * specifies a shared folder name and an
- * optional path within the shared folder.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHI_ShellAction(const char *actionURI, // IN
- const char *targetURI, // IN
- const char **locations, // IN
- int numLocations) // IN
-{
- return GHIPlatformShellAction(ghiPlatformData,
- actionURI, targetURI,
- locations, numLocations);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHI_SetGuestHandler --
- *
- * Set the handler for the specified filetype (or URL protocol) to the
- * given value. One of suffix, mimeType or UTI must be specified. Some platforms
- * (windows) only support certain identifiers (suffixes in the case of windows).
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHI_SetGuestHandler(const char *suffix, // IN/OPT
- const char *mimeType, // IN/OPT
- const char *UTI, // IN/OPT
- const char *actionURI, // IN
- const char *targetURI) // IN
-{
- return GHIPlatformSetGuestHandler(ghiPlatformData,
- suffix, mimeType, UTI,
- actionURI, targetURI);
-}
-
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHI_RestoreDefaultGuestHandler --
- *
- * Restore the handler for a given type to the value in use before any
- * changes by tools. One of suffix, mimeType or UTI must be specified.
- * Some platforms (windows) only support certain identifiers (suffixes
- * in the case of windows).
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHI_RestoreDefaultGuestHandler(const char *suffix, // IN/OPT
- const char* mimetype, // IN/OPT
- const char *UTI) // IN/OPT
-{
- return GHIPlatformRestoreDefaultGuestHandler(ghiPlatformData, suffix, mimetype, UTI);
-}
-
-/**
- * @brief Send a mouse or keyboard event to a notification icon.
- *
- * @param[in] iconId Icon Identifier.
- * @param[in] event Event Details
- * @param[in] x Mouse Position
- * @param[in] y Mouse Position
- *
- * @retval TRUE
- * @retval FALSE
- */
-
-Bool
-GHI_TrayIconSendEvent(const char *iconID,
- uint32 event,
- uint32 x,
- uint32 y)
-{
- return GHIPlatformTrayIconSendEvent(ghiPlatformData, iconID, event, x, y);
-}
-
-
-/**
- * @brief Start sending tray icon updates to the VMX.
- *
- * @retval TRUE The RPC succeeded.
- * @retval FALSE The RPC failed.
- */
-
-Bool
-GHI_TrayIconStartUpdates()
-{
- return GHIPlatformTrayIconStartUpdates(ghiPlatformData);
-}
-
-/**
- * @brief Stop sending tray icon updates to the VMX.
- *
- * @retval TRUE Operation Succeeded.
- * @retval FALSE Operation Failed.
- */
-
-Bool
-GHI_TrayIconStopUpdates()
-{
- return GHIPlatformTrayIconStopUpdates(ghiPlatformData);
-}
-
-
-/**
- * @brief Set the specified window to be focused.
- *
- * @param[in] windowId Window handle to be focused, passing zero handle
- * implies that no visible window will be focused in the guest.
- *
- * @retval TRUE Operation succeeded.
- * @retval FALSE Operation failed.
- */
-
-Bool
-GHI_SetFocusedWindow(int32 windowId)
-{
- return GHIPlatformSetFocusedWindow(ghiPlatformData, windowId);
-}
-
-
-/**
- * @brief Get the hash (or timestamp) of information returned by
- * GHIPlatformGetBinaryInfo
- *
- * @param[in] request Request containing which executable to get the hash for.
- * @param[out] reply Reply to be filled with the hash, the caller must free this memory.
- *
- * @retval TRUE Operation succeeded.
- * @retval FALSE Operation failed.
- */
-
-Bool
-GHI_GetExecInfoHash(const char *execPath,
- char **execInfoHash)
-{
- return GHIPlatformGetExecInfoHash(ghiPlatformData, execPath, execInfoHash);
-}
-
-
-/**
- * @brief Sets the OutlookTempHgfsPath value used by hostOpen.
- *
- * When hostOpen is invoked on a file that is not on an hgfs share, it typically
- * displays an error message. However, as a special case for Microsoft Outlook
- * attachments, hostOpen will copy the file to an hgfs share, then send an RPC
- * to the host to cause it to open the file in the default host application.
- *
- * @param[in] targetURI Pointer to URI to be used as the folder for temp files.
- *
- * @returns TRUE if the OutlookTempHgfsPath value was set.
- */
-Bool
-GHI_SetOutlookTempFolder(const char *targetURI)
-{
- return GHIPlatformSetOutlookTempFolder(ghiPlatformData, targetURI);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHI_RegisterNotifyIconCallback --
- *
- * Register the supplied callback object with the
- * Notify Icon Manager.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-void
-GHI_RegisterNotifyIconCallback(NotifyIconCallback *notifyIconCallback) // IN
-{
- GHIPlatformRegisterNotifyIconCallback(notifyIconCallback);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHI_UnregisterNotifyIconCallback --
- *
- * Unregister the supplied callback object with the
- * Notify Icon Manager.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-void
-GHI_UnregisterNotifyIconCallback(NotifyIconCallback *notifyIconCallback) // IN
-{
- GHIPlatformUnregisterNotifyIconCallback(notifyIconCallback);
-}
-
-
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * ghIntegration.h --
- *
- * Commands for guest host integration.
- */
-
-#ifndef _GH_INTEGRATION_H_
-#define _GH_INTEGRATION_H_
-
-#if defined(__cplusplus)
-#if !defined(OPEN_VM_TOOLS) && !defined(__FreeBSD__) && !defined(sun) && !defined(__APPLE__)
-#include "appUtilFileTypes.h"
-#include "stringxx/string.hh"
-#endif // !OPEN_VM_TOOLS && !__FREEBSD__ && !sun && !__APPLE__
-
-#include <vector>
-#include <string>
-#include <list>
-#endif // __cplusplus
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <glib.h>
-
-#include "vmware.h"
-#include "dynbuf.h"
-
-typedef Bool (*GHILaunchMenuChangeRPCFn)(int numFolderKeys,
- const char **folderKeysChanged);
-typedef Bool (*GHISendTrashFolderStateRPCFn)(Bool empty);
-
-typedef struct GHIHostCallbacks {
- GHILaunchMenuChangeRPCFn launchMenuChange;
-} GHIHostCallbacks;
-
-Bool GHI_IsSupported(void);
-void GHI_Init(GMainLoop *mainLoop, const char **envp, GHIHostCallbacks hostCallbacks);
-void GHI_Cleanup(void);
-
-Bool GHI_ShellOpen(const char *fileURIUtf8);
-Bool GHI_ShellAction(const char *actionURI,
- const char *targetURI,
- const char **locations,
- int numLocations);
-
-Bool GHI_SetGuestHandler(const char *suffix, const char *mimeType, const char *UTI,
- const char *actionURI, const char *targetURI);
-Bool GHI_RestoreDefaultGuestHandler(const char *suffix,
- const char* mimetype,
- const char *UTI);
-Bool GHI_SetOutlookTempFolder(const char *targetURI);
-
-Bool GHI_TrayIconSendEvent(const char *iconID,
- uint32 event,
- uint32 x,
- uint32 y);
-Bool GHI_TrayIconStartUpdates(void);
-Bool GHI_TrayIconStopUpdates(void);
-
-Bool GHI_SetFocusedWindow(int32 windowId);
-
-Bool GHI_GetExecInfoHash(const char *execPath,char **execInfoHash);
-
-#ifndef _WIN32
-const char *GHIX11_FindDesktopUriByExec(const char *exec);
-#endif
-
-#ifdef __cplusplus
-}; /* extern "C" */
-#endif // __cplusplus
-
-#ifdef __cplusplus
-namespace vmware { namespace tools {
-
-class NotifyIconCallback;
-
-} /* namespace tools */ } /* namespace vmware */
-
-void GHI_RegisterNotifyIconCallback(vmware::tools::NotifyIconCallback *notifyIconCallback);
-void GHI_UnregisterNotifyIconCallback(vmware::tools::NotifyIconCallback *notifyIconCallback);
-
-#if !defined(OPEN_VM_TOOLS) && !defined(__FreeBSD__) && !defined(sun) && !defined(__APPLE__)
-const FileTypeList& GHI_GetBinaryHandlers(const char *pathUtf8);
-#endif // !OPEN_VM_TOOLS && !__FreeBSD__ && !sun && !__APPLE__
-
-typedef struct GHIBinaryIconInfo {
- uint32 width;
- uint32 height;
- std::vector<uint8> dataBGRA;
-} GHIBinaryIconInfo;
-
-Bool GHI_GetBinaryInfo(const char *pathUriUtf8, std::string &friendlyName, std::list<GHIBinaryIconInfo> &iconList);
-
-#if !defined(OPEN_VM_TOOLS) && !defined(__FreeBSD__) && !defined(sun) && !defined(__APPLE__)
-Bool GHI_OpenStartMenuTree(const char *rootUtf8, uint32 flags, uint32 &handle, uint32 &numItems);
-Bool GHI_GetStartMenuItem(uint32 handle,
- uint32 itemIndex,
- Bool &isSubmenu,
- utf::string &menuPath,
- utf::string &itemPathURI,
- utf::string &itemName);
-Bool GHI_CloseStartMenuTree(uint32 handle);
-#endif // !OPEN_VM_TOOLS && !__FreeBSD__ && !sun && !__APPLE__
-#endif // __cplusplus
-
-#endif // _GH_INTEGRATION_H_
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * ghIntegrationInt.h --
- *
- * Platform specific functionality
- */
-
-#ifndef _GH_INTEGRATION_INT_H_
-#define _GH_INTEGRATION_INT_H_
-
-#include "ghIntegration.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "dynbuf.h"
-
-typedef struct _GHIPlatform GHIPlatform;
-
-/*
- * Implemented by ghIntegration[Win32|X11|Cocoa (ha!)].c
- */
-
-Bool GHIPlatformIsSupported(void);
-GHIPlatform *GHIPlatformInit(GMainLoop *mainLoop, const char **envp, GHIHostCallbacks hostcallbacks);
-void GHIPlatformCleanup(GHIPlatform *ghip);
-Bool GHIPlatformShellOpen(GHIPlatform *ghip,
- const char *fileUtf8);
-Bool GHIPlatformShellAction(GHIPlatform *ghip,
- const char *actionURI,
- const char *targetURI,
- const char **locations,
- int numLocations);
-Bool GHIPlatformSetGuestHandler(GHIPlatform *ghip,
- const char *suffix,
- const char *mimeType,
- const char *UTI,
- const char *actionURI,
- const char *targetURI);
-Bool GHIPlatformRestoreDefaultGuestHandler(GHIPlatform *ghip,
- const char *suffix,
- const char *mimetype,
- const char *UTI);
-
-/*
- * Set the temporary folder used by Outlook to store attachments.
- */
-Bool GHIPlatformSetOutlookTempFolder(GHIPlatform* ghip, const char *targetURI);
-
-/*
- * Send a mouse event to a tray icon.
- */
-Bool GHIPlatformTrayIconSendEvent(GHIPlatform *ghip,
- const char *iconID,
- uint32 event,
- uint32 x,
- uint32 y);
-
-/*
- * Start sending tray icon updates to the VMX.
- */
-Bool GHIPlatformTrayIconStartUpdates(GHIPlatform *ghip);
-
-/*
- * Stop sending tray icon updates to the VMX.
- */
-Bool GHIPlatformTrayIconStopUpdates(GHIPlatform *ghip);
-
-/*
- * Set the specified window to be focused.
- */
-Bool GHIPlatformSetFocusedWindow(GHIPlatform *ghip, int32 windowId);
-
-/*
- * Get the hash (or timestamp) of information returned by get.binary.info.
- */
-Bool GHIPlatformGetExecInfoHash(GHIPlatform *ghip,
- const char *execPath,
- char **execInfoHash);
-
-#ifndef _WIN32
-const gchar *
-GHIX11FindDesktopUriByExec(GHIPlatform *ghip,
- const char *exec);
-#endif
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#ifdef __cplusplus
-namespace vmware { namespace tools {
-
-class NotifyIconCallback;
-
-} /* namespace tools */ } /* namespace vmware */
-
-void GHIPlatformRegisterNotifyIconCallback(vmware::tools::NotifyIconCallback *notifyIconCallback);
-void GHIPlatformUnregisterNotifyIconCallback(vmware::tools::NotifyIconCallback *notifyIconCallback);
-
-#if !defined(OPEN_VM_TOOLS) && !defined(__FreeBSD__) && !defined(sun) && !defined(__APPLE__)
-const FileTypeList& GHIPlatformGetBinaryHandlers(GHIPlatform *ghip, const char *pathUtf8);
-
-Bool GHIPlatformOpenStartMenuTree(GHIPlatform *ghip,
- const char *rootUtf8,
- uint32 flags,
- uint32 &handle,
- uint32 &numItems);
-Bool GHIPlatformGetStartMenuItem(GHIPlatform *ghip,
- uint32 handle,
- uint32 itemIndex,
- Bool &isSubmenu,
- utf::string &menuPath,
- utf::string &itemPathURI,
- utf::string &itemName);
-Bool GHIPlatformCloseStartMenuTree(GHIPlatform *ghip,
- uint32 handle);
-#endif // !OPEN_VM_TOOLS && !__FreeBSD__ && !sun && !__APPLE__
-
-Bool GHIPlatformGetBinaryInfo(GHIPlatform *ghip, const char *pathUriUtf8, std::string &friendlyName, std::list<GHIBinaryIconInfo> &iconList);
-
-#endif // __cplusplus
-
-#endif // _GH_INTEGRATION_INT_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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.
- *
- *********************************************************/
-
-/*
- * ghiX11icon.h --
- *
- * Declares GHIX11Icon type and utility functions.
- */
-
-#ifndef _GHIX11ICON_H_
-#define _GHIX11ICON_H_
-
-#include <list>
-#include <glib.h>
-#include "ghIntegrationInt.h"
-
-struct GHIBinaryIconInfo;
-
-Bool GHIX11IconGetIconsForDesktopFile(const char* desktopFile,
- std::list<GHIBinaryIconInfo>& iconList);
-Bool GHIX11IconGetIconsByName(const char* iconName,
- std::list<GHIBinaryIconInfo>& iconList);
-
-
-#endif // ifndef _GHIX11ICON_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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.
- *
- *********************************************************/
-
-/*
- * icon.c --
- *
- * GHI/X11 icon collection code.
- */
-
-
-#include <math.h>
-
-#include <gtk/gtk.h>
-#include <glib.h>
-#include <gio/gdesktopappinfo.h>
-
-extern "C" {
-#include "vmware.h"
-#include "guest_msg_def.h"
-}
-
-#include "ghiX11icon.h"
-
-
-/*
- * GHI/X11 still pumps icons over GuestMsg, which limits us to 64K. Until we
- * switch transports, we'll have to scale down icons to fit within limits.
- */
-
-static const size_t MAX_ICON_SIZE = GUESTMSG_MAX_IN_SIZE - 1024;
-
-
-/*
- * Local function declarations.
- */
-
-static void AppendFileToArray(const gchar* iconPath,
- std::list<GHIBinaryIconInfo>& iconList);
-static void AppendPixbufToArray(const GdkPixbuf* pixbuf,
- std::list<GHIBinaryIconInfo>& iconList,
- bool scaleHint = false);
-static gint* GetIconSizesDescending(GtkIconTheme *iconTheme,
- const gchar* iconName);
-static Bool GetIconsForGIcon(GIcon* gicon,
- std::list<GHIBinaryIconInfo>& iconList);
-static GdkPixbuf* ShrinkPixbuf(const GdkPixbuf* pixbuf, size_t maxSize);
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GHIX11IconGetIconsForDesktopFile --
- *
- * Given an application's .desktop file, look up and return the app's icons
- * as BGRA data. Icons are sorted in descending order by size.
- *
- * Results:
- * Returns FALSE if any errors were encountered and TRUE otherwise.
- *
- * Side effects:
- * iconList.size() may grow.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-GHIX11IconGetIconsForDesktopFile(const char* desktopFile, // IN
- std::list<GHIBinaryIconInfo>& iconList) // OUT
-{
- GDesktopAppInfo* desktopAppInfo = NULL;
- GIcon* gicon = NULL;
- Bool success = FALSE;
-
- desktopAppInfo = g_desktop_app_info_new_from_filename(desktopFile);
- if (desktopAppInfo) {
- GAppInfo* appInfo = (GAppInfo*)G_APP_INFO(desktopAppInfo);
- gicon = g_app_info_get_icon(appInfo);
- if (gicon) {
- success = GetIconsForGIcon(gicon, iconList);
- }
- g_object_unref(desktopAppInfo);
- }
-
- return success;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GHIX11IconGetIconsByName --
- *
- * Try to find icons identified by a string. The string may refer to a
- * generic name leading to searching an icon theme, or it may be an
- * absolute path to an icon file.
- *
- * Results:
- * Returns FALSE if any errors were encountered and TRUE otherwise.
- *
- * Side effects:
- * iconList.size() may grow.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-GHIX11IconGetIconsByName(const char* iconName, // IN
- std::list<GHIBinaryIconInfo>& iconList) // OUT
-{
- GIcon *gicon;
- Bool retval = FALSE;
-
- gicon = g_icon_new_for_string(iconName, NULL);
- if (gicon) {
- retval = GetIconsForGIcon(gicon, iconList);
- g_object_unref(G_OBJECT(gicon));
- }
-
- return retval;
-}
-
-
-/*
- * Local functions
- */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GetIconsForGIcon --
- *
- * Given a GLib GIcon, search the default icon theme or filesystem for
- * icons.
- *
- * Results:
- * Returns FALSE if any errors were encountered and TRUE otherwise.
- *
- * Side effects:
- * iconList.size() may grow.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GetIconsForGIcon(GIcon* gicon, // IN
- std::list<GHIBinaryIconInfo>& iconList) // OUT
-{
- gchar* iconName = NULL;
- GtkIconTheme* iconTheme;
- Bool success = FALSE;
-
- ASSERT(gicon);
-
- /*
- * We can handle two icon types, themed and file. A themed icon is
- * provided by and varies by icon theme whereas a file icon is stored
- * in a single file. (There's a special case where GIO thinks we have
- * a themed icon, but it turns out to be a file icon. More on that later.)
- */
-
- iconName = g_icon_to_string(gicon);
- iconTheme = gtk_icon_theme_get_default();
-
- if (G_IS_THEMED_ICON(gicon) && gtk_icon_theme_has_icon(iconTheme, iconName)) {
-
- /*
- * Sweet - GTK claims that our icon is themed and can give us pixbufs for
- * it at various sizes.
- *
- * Remember what I said about GIO thinking we have a themed icon that might
- * not be? If an icon doesn't have a size, then it's one of those such
- * icons, and we have to fall back to loading directly from a file ourselves.
- */
-
- gint* iconSizes = GetIconSizesDescending(iconTheme, iconName);
-
- if (iconSizes && *iconSizes != 0) {
- gint* sizeIter;
-
- for (sizeIter = iconSizes; *sizeIter; sizeIter++) {
- GdkPixbuf* pixbuf;
-
- pixbuf = gtk_icon_theme_load_icon(iconTheme, iconName, *sizeIter,
- (GtkIconLookupFlags)0, NULL);
- if (pixbuf) {
- AppendPixbufToArray(pixbuf, iconList);
- g_object_unref(pixbuf);
- }
- }
- } else if (iconSizes && *iconSizes == 0) {
- GtkIconInfo* iconInfo;
-
- iconInfo = gtk_icon_theme_lookup_icon(iconTheme, iconName, 0,
- (GtkIconLookupFlags)0);
- if (iconInfo) {
- AppendFileToArray(gtk_icon_info_get_filename(iconInfo), iconList);
- gtk_icon_info_free(iconInfo);
- }
- }
-
- g_free(iconSizes);
- } else if (G_IS_FILE_ICON(gicon)) {
- GFileIcon* fileIcon;
- GFile* file;
- char* path;
-
- fileIcon = G_FILE_ICON(gicon);
- file = g_file_icon_get_file(fileIcon);
- path = g_file_get_path(file);
- ASSERT(path);
-
- AppendFileToArray(path, iconList);
-
- g_free(path);
- } else {
- /* Give up. */
- goto out;
- }
-
- success = TRUE;
-
-out:
- if (iconName) {
- g_free(iconName);
- }
- return success;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * AppendFileToArray --
- *
- * Load an icon from a file into a pixbuf, then append it to a GPtrArray of
- * GHIX11Icons.
- *
- * Results:
- * Appends an icon on success, no-op on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-AppendFileToArray(const gchar* iconPath, // IN
- std::list<GHIBinaryIconInfo>& iconList) // OUT
-{
- GdkPixbuf* pixbuf;
-
- if ((pixbuf = gdk_pixbuf_new_from_file(iconPath, NULL)) != NULL) {
- AppendPixbufToArray(pixbuf, iconList, true);
- g_object_unref(pixbuf);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * AppendPixbufToArray --
- *
- * Appends a pixbuf to a GPtrArray of GHIX11Icons.
- *
- * Results:
- * Appends an icon on success, no-op on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-AppendPixbufToArray(
- const GdkPixbuf* pixbuf, // IN
- std::list<GHIBinaryIconInfo>& iconList, // OUT
- bool scaleHint) // IN: Scale icon to fit GuestMsg
-{
- GHIBinaryIconInfo ghiIcon;
- guchar* pixels;
- guint width;
- guint height;
- guint x, y;
- guint rowstride;
- guint n_channels;
- guint bgraStride;
- bool scaled = false;
- GdkPixbuf *scaledPixbuf = NULL;
-
-rescaled:
- ASSERT(pixbuf);
- ASSERT(gdk_pixbuf_get_colorspace(pixbuf) == GDK_COLORSPACE_RGB);
- ASSERT(gdk_pixbuf_get_bits_per_sample(pixbuf) == 8);
-
- rowstride = gdk_pixbuf_get_rowstride(pixbuf);
- n_channels = gdk_pixbuf_get_n_channels(pixbuf);
- pixels = gdk_pixbuf_get_pixels(pixbuf);
-
- ghiIcon.width = width = gdk_pixbuf_get_width(pixbuf);
- ghiIcon.height = height = gdk_pixbuf_get_height(pixbuf);
- bgraStride = width * 4;
- ghiIcon.dataBGRA.resize(height * bgraStride);
-
- if ( !scaled
- && scaleHint
- && height * bgraStride > MAX_ICON_SIZE) {
- scaled = true;
- pixbuf = scaledPixbuf = ShrinkPixbuf(pixbuf, MAX_ICON_SIZE);
- goto rescaled;
- }
-
- /* GetBinaryInfo icons are bottom-to-top. */
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- guchar* b; // Pointer to BGRA data in ghiIcon.
- guchar* p; // Pointer to RGBA data in GdkPixbuf
- gint bgraOffset = y * bgraStride + x * 4;
- gint pixbufOffset = (height - y - 1) * rowstride + x * n_channels;
-
- b = &ghiIcon.dataBGRA[bgraOffset];
- p = &pixels[pixbufOffset];
-
- b[0] = p[2];
- b[1] = p[1];
- b[2] = p[0];
- b[3] = (n_channels > 3) ? p[3] : 0xFF;
- }
- }
-
- iconList.push_back(ghiIcon);
-
- if (scaledPixbuf) {
- g_object_unref(G_OBJECT(scaledPixbuf));
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GetIconSizesDescending --
- *
- * Query an icon theme for an icon's sizes. Return the sizes as a gint
- * array in descending order.
- *
- * Results:
- * Pointer to a gint array on success or NULL on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static int
-DescendingIntCmp(const void* a,
- const void* b)
-{
- gint ia = *(gint* )a;
- gint ib = *(gint* )b;
-
- return (ia < ib) ? 1 : (ia == ib) ? 0 : -1;
-}
-
-static gint*
-GetIconSizesDescending(GtkIconTheme* iconTheme, // IN
- const gchar* iconName) // IN
-{
- gint* iconSizes = NULL;
- gint* iter;
- size_t nsizes;
-
- if (!gtk_icon_theme_has_icon(iconTheme, iconName)) {
- return NULL;
- }
-
- iconSizes = gtk_icon_theme_get_icon_sizes(iconTheme, iconName);
- ASSERT(iconSizes);
-
- /*
- * iconSizes is a 0-terminated array. If there are no sizes or the
- * array has only 1 element, this function has no remaining work to do.
- * (No point sorting a 1 element array.)
- */
- if (!iconSizes || *iconSizes == 0) {
- return iconSizes;
- }
-
- /*
- * Sort the array in descending order. First we have to determine its
- * size, then we'll just pass it off to qsort. Note that we don't consider
- * the final, terminating element when sorting, because the icon array may
- * contain a -1 to signify a scalable icon.
- */
- for (iter = iconSizes, nsizes = 0; *iter; iter++, nsizes++);
- qsort(iconSizes, nsizes, sizeof *iter, DescendingIntCmp);
-
- return iconSizes;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ShrinkPixbuf --
- *
- * Scale a pixbuf to fit within transport size constraints.
- *
- * Results:
- * Pointer to new pixbuf. Caller should free with g_object_unref.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-GdkPixbuf*
-ShrinkPixbuf(const GdkPixbuf* pixbuf, // IN
- size_t maxSize) // IN: Must scale to less than this.
-{
- GdkPixbuf *newIcon;
- volatile double newWidth;
- volatile double newHeight;
- volatile double scaleFactor;
-
- newWidth = gdk_pixbuf_get_width(pixbuf);
- newHeight = gdk_pixbuf_get_height(pixbuf);
- scaleFactor = maxSize / (newWidth * newHeight * 4.0);
- /*
- * Ensures that we remove at least a little bit of data from the icon.
- * Otherwise we can get things like scalefactors of '0.999385' which result
- * in an image of exactly the same size. A scaleFactor of 0.95 will remove at
- * least one row or column from any icon large enough to go past the limit.
- */
- scaleFactor = MIN(scaleFactor, 0.95);
-
- newWidth *= scaleFactor;
- newHeight *= scaleFactor;
- newIcon = gdk_pixbuf_scale_simple(pixbuf,
- (int)ceil(newWidth),
- (int)ceil(newHeight),
- GDK_INTERP_HYPER);
- return newIcon;
-}
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2008-2010 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.
- *
- *********************************************************/
-
-
-/*
- * ghIntegrationX11.c --
- *
- * Guest-host integration implementation for POSIX-compliant platforms that run X11.
- *
- * The main tasks done by this code are reading in the system's .desktop files to turn
- * them into an internal representation of available applications on the system
- * (implemented by GHIPlatformReadAllApplications, GHIPlatformReadApplicationsDir,
- * GHIPlatformReadDesktopFile, and kin), and feeding portions of that internal
- * representation to the host upon request
- * (GHIPlatform{OpenStartMenuTree,GetStartMenuItem,CloseStartMenuTree}).
- */
-
-
-#include <stdio.h>
-#include <limits.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <libgen.h>
-
-#ifndef GTK2
-#error "Gtk 2.0 is required"
-#endif
-
-#include <gtk/gtk.h>
-#include <gtkmm.h>
-#include <glibmm.h>
-#include <giomm.h>
-#include <glib.h>
-#include <gdk-pixbuf/gdk-pixbuf-core.h>
-#include <sigc++/sigc++.h>
-
-// gdkx.h includes Xlib.h, which #defines Bool.
-#include <gdk/gdkx.h>
-#undef Bool
-
-#include <gio/gdesktopappinfo.h>
-
-extern "C" {
-#include "vmware.h"
-#include "vmware/tools/guestrpc.h"
-#include "base64.h"
-#include "dbllnklst.h"
-#include "debug.h"
-#include "util.h"
-#include "region.h"
-#include "unity.h"
-#include "unityCommon.h"
-#include "system.h"
-#include "codeset.h"
-#include "imageUtil.h"
-#include "str.h"
-#include "strutil.h"
-#include <paths.h>
-#include "vm_atomic.h"
-#include "mntinfo.h"
-#include "guest_msg_def.h"
-#include "Uri.h"
-#include "xdg.h"
-};
-
-#define URI_TEXTRANGE_EQUAL(textrange, str) \
- (((textrange).afterLast - (textrange).first) == (ssize_t) strlen((str)) \
- && !strncmp((textrange).first, (str), (textrange).afterLast - (textrange).first))
-
-#include "appUtil.h"
-#include "ghIntegration.h"
-#include "ghIntegrationInt.h"
-#include "ghiX11icon.h"
-
-#ifdef REDIST_GMENU
-# include "vmware/tools/ghi/menuItemManager.hh"
-using vmware::tools::ghi::MenuItemManager;
-using vmware::tools::ghi::MenuItem;
-#endif
-
-#include "vmware/tools/ghi/pseudoAppMgr.hh"
-using vmware::tools::ghi::PseudoAppMgr;
-using vmware::tools::ghi::PseudoApp;
-
-
-using vmware::tools::NotifyIconCallback;
-
-/*
- * These describe possible start menu item flags. It should come from ghiCommon.h
- * eventually.
- */
-#define UNITY_START_MENU_ITEM_DIRECTORY (1 << 0)
-
-/*
- * This macro provides an estimate of how much space an icon might take beyond the actual
- * icon data when returned from unity.get.binary.info. This makes space for the
- * width/height/size strings, and adds enough padding to give some breathing room just in
- * case.
- *
- * > This is only an estimate. <
- */
-#define ICON_SPACE_PADDING (sizeof "999x999x65535x" + 25)
-
-
-/*
- * GHI/X11 context object
- */
-
-struct _GHIPlatform {
- GTree *apps; // Tree of GHIMenuDirectory's, keyed & ordered by their dirname
- GHashTable *appsByExecutable; // Translates full executable path to GHIMenuItem
- GHashTable *appsByDesktopEntry; // Translates full .desktop path to GHIMenuItem
- /*
- * Translates arbitrary executable paths as discovered through
- * UnityPlatformGetWindowPaths to a .desktop-ful executable URI.
- *
- * Example:
- * (key) /usr/lib/firefox-3.6.3/firefox-bin (via Firefox window's _NET_WM_PID)
- * (value) file:///usr/bin/firefox?DesktopEntry=/usr/share/applications/firefox.desktop
- */
- GHashTable *appsByWindowExecutable;
-
- /* Pre-wrapper script environment. See @ref System_GetNativeEnviron. */
- std::vector<Glib::ustring> nativeEnviron;
-
- /* Callbacks to send data (RPCs) to the host */
- GHIHostCallbacks hostCallbacks;
-
-#ifdef REDIST_GMENU
- /* Launch menu item layout generator thing. */
- MenuItemManager *menuItemManager;
-#endif
-};
-
-/*
- * The GHIMenuItem object represents an individual leaf-node menu item (corresponding to
- * a .desktop file).
- */
-typedef struct {
- char *exepath; // The full exe path for use in GHIPlatform::appsByExecutable
- char *keyfilePath; // Key to GHIPlatform::appsByDesktopEntry, used in %k field code
- GKeyFile *keyfile; // glib data structure representing the parsed .desktop file
-} GHIMenuItem;
-
-/*
- * Represents a "start menu folder" so to speak.
- */
-typedef struct {
- const char *dirname; // The .desktop category that this object represents
- const char *prettyDirname; // (optional) A prettier version of dirname.
- GPtrArray *items; // Array of pointers to GHIMenuItems
-} GHIMenuDirectory;
-
-/*
- * Represents an active handle for traversing a menu.
- */
-typedef struct {
- int handleID;
- enum { LAUNCH_FOLDER, FIXED_FOLDER, DIRECTORY_FOLDER } handleType;
- GHIMenuDirectory *gmd; // Only set for DIRECTORY_FOLDER handles
-} GHIMenuHandle;
-
-/*
- * This is used to help us find the Nth GHIMenuDirectory node in the GHIPlatform::apps
- * tree, an operation that is needed as part of GHIPlatformGetStartMenuItem...
- */
-typedef struct {
- int currentItem;
- int desiredItem;
- GHIMenuDirectory *gmd; // OUT - pointer to the Nth GHIMenuDirectory
-} GHITreeTraversal;
-
-
-/*
- * GHI capabilities for this platform.
- */
-/*
- * XXX TODO: re-enable once ShellAction is implemented.
- */
-/*
-static GuestCapabilities platformGHICaps[] = {
- GHI_CAP_CMD_SHELL_ACTION,
- GHI_CAP_SHELL_ACTION_BROWSE,
- GHI_CAP_SHELL_ACTION_RUN,
- GHI_CAP_SHELL_LOCATION_HGFS
-};
-*/
-
-#if !defined(OPEN_VM_TOOLS)
-/*
- * An empty file type list - a reference to this can be returned by
- * GHIPlatformGetBinaryHandlers() in some circumstances.
- */
-static FileTypeList sEmptyFileTypeList;
-#endif // OPEN_VM_TOOLS
-
-
-static bool AppInfoLaunchEnv(GHIPlatform* ghip, GAppInfo* appInfo);
-static void OnMenusChanged(GHIPlatform* ghip);
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformIsSupported --
- *
- * Determine whether this guest supports guest host integration.
- *
- * Results:
- * TRUE if the guest supports GHI
- * FALSE otherwise
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHIPlatformIsSupported(void)
-{
- const char *desktopEnv = Xdg_DetectDesktopEnv();
- Bool supported = (g_strcmp0(desktopEnv, "GNOME") == 0) ||
- (g_strcmp0(desktopEnv, "KDE") == 0) ||
- (g_strcmp0(desktopEnv, "XFCE") == 0);
- if (!supported) {
- g_message("GHI not available under unsupported desktop environment %s\n",
- desktopEnv ? desktopEnv : "(nil)");
- }
- return supported;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformInit --
- *
- * Sets up the platform-specific GHI state.
- *
- * Results:
- * Pointer to platform-specific data (may be NULL).
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-GHIPlatform *
-GHIPlatformInit(GMainLoop *mainLoop, // IN
- const char **envp, // IN
- GHIHostCallbacks hostCallbacks) // IN
-{
- GHIPlatform *ghip;
- const char *desktopEnv;
-
- Gtk::Main::init_gtkmm_internals();
-
- if (!GHIPlatformIsSupported()) {
- /*
- * Don't bother allocating resources if running under an unsupported
- * desktop environment.
- */
- return NULL;
- }
-
- ghip = (GHIPlatform *) Util_SafeCalloc(1, sizeof *ghip);
- ghip->appsByWindowExecutable =
- g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- ghip->hostCallbacks = hostCallbacks;
- AppUtil_Init();
-
- const char** tmp;
- for (tmp = envp; *tmp; tmp++) {
- /*
- * PR 685881: DESKTOP_AUTOSTART_ID was proposed on the xdg@freedesktop.org
- * mailing list, but doesn't seem like it made it to a final spec.
- *
- * http://lists.freedesktop.org/archives/xdg/2007-January/007436.html
- *
- * It refers to a XSMP session manager client ID which shouldn't be
- * passed to children. Having this environment variable breaks launching
- * nautilus w/o arguments. (Aside, GNOME fixed this upstream in response
- * to https://bugzilla.gnome.org/show_bug.cgi?id=649063.)
- */
- if (g_str_has_prefix(*tmp, "DESKTOP_AUTOSTART_ID=")) {
- continue;
- }
-
- ghip->nativeEnviron.push_back(*tmp);
- }
-
- /*
- * PR 698958: Unity: There can be only one. (Disable Ubuntu global application menu.)
- * See https://wiki.ubuntu.com/DesktopExperienceTeam/ApplicationMenu#Troubleshooting
- */
- ghip->nativeEnviron.push_back("UBUNTU_MENUPROXY=");
-
- desktopEnv = Xdg_DetectDesktopEnv();
- ASSERT(desktopEnv); // Asserting based on GHIPlatformIsSupported check above.
- g_desktop_app_info_set_desktop_env(desktopEnv);
-
-#ifdef REDIST_GMENU
- ghip->menuItemManager = new MenuItemManager(desktopEnv);
- sigc::slot<void,GHIPlatform*> menuSlot = sigc::ptr_fun(&OnMenusChanged);
- ghip->menuItemManager->menusChanged.connect(sigc::bind(menuSlot, ghip));
- OnMenusChanged(ghip);
-#endif
-
- return ghip;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformRegisterCaps --
- *
- * Register guest platform specific capabilities with the VMX.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-GHIPlatformRegisterCaps(GHIPlatform *ghip) // IN
-{
- ASSERT(ghip);
- //ASSERT(platformGHICaps);
-
- /*
- * XXX TODO: re-enable once ShellAction is implemented.
- */
- //AppUtil_SendGuestCaps(platformGHICaps, ARRAYSIZE(platformGHICaps), TRUE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformUnregisterCaps --
- *
- * Register guest platform specific capabilities with the VMX.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-GHIPlatformUnregisterCaps(GHIPlatform *ghip) // IN
-{
- ASSERT(ghip);
- //ASSERT(platformGHICaps);
-
- /*
- * XXX TODO: re-enable once ShellAction is implemented.
- */
- //AppUtil_SendGuestCaps(platformGHICaps, ARRAYSIZE(platformGHICaps), FALSE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformCleanup --
- *
- * Tears down the platform-specific GHI state.
- *
- * Results:
- * None.
- *
- * Side effects:
- * GHIPlatform is no longer valid.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-GHIPlatformCleanup(GHIPlatform *ghip) // IN
-{
- if (!ghip) {
- return;
- }
-
-#ifdef REDIST_GMENU
- delete ghip->menuItemManager;
-#endif
- g_hash_table_destroy(ghip->appsByWindowExecutable);
- free(ghip);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GHIPlatformRegisterNotifyIconCallback / GHIPlatformUnregisterNotifyIconCallback --
- *
- * Register/Unregister the NotifyIcon Callback object. Since notification icons
- * (aka Tray icons) are unsupported on Linux guests this function does nothing.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Adds data into the DynBuf.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-GHIPlatformRegisterNotifyIconCallback(NotifyIconCallback *notifyIconCallback) // IN
-{
-}
-
-void GHIPlatformUnregisterNotifyIconCallback(NotifyIconCallback *notifyIconCallback) // IN
-{
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformGetBinaryInfo --
- *
- * Get binary information (app name and icons). We're passed app info in
- * pathURIUtf8 (in URI format), and we find the app info by looking up the
- * path in GHIPlatform->appsByExecutable. Once we find it, we can retrieve
- * info on the app from the .desktop file.
- *
- * Results:
- * TRUE if everything went ok, FALSE otherwise.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHIPlatformGetBinaryInfo(GHIPlatform *ghip, // IN: platform-specific state
- const char *pathURIUtf8, // IN: full path to the binary file
- std::string &friendlyName, // OUT: Friendly name
- std::list<GHIBinaryIconInfo> &iconList) // OUT: Icons
-{
- const char *realCmd = NULL;
-#if 0
- char *keyfilePath = NULL;
- unsigned long windowID = 0;
- gpointer freeMe = NULL;
-#endif
- UriParserStateA state;
- UriUriA uri;
-
- ASSERT(ghip);
- ASSERT(pathURIUtf8);
-
- memset(&state, 0, sizeof state);
- memset(&uri, 0, sizeof uri);
- state.uri = &uri;
-
- /* Strip query component. */
- size_t uriSize = strlen(pathURIUtf8) + 1;
- gchar *uriSansQuery = (gchar*)g_alloca(uriSize);
- memcpy(uriSansQuery, pathURIUtf8, uriSize);
- gchar *tmp = strchr(uriSansQuery, '?');
- if (tmp) { *tmp = '\0'; }
-
- if (uriSansQuery[0] == '/') {
- realCmd = uriSansQuery;
- } else if (uriParseUriA(&state, uriSansQuery) == URI_SUCCESS) {
- if (URI_TEXTRANGE_EQUAL(uri.scheme, "file")) {
- gchar* tmp = (gchar*)g_alloca(strlen(uriSansQuery) + 1);
- uriUriStringToUnixFilenameA(uriSansQuery, tmp);
-
- Glib::ustring unixFile;
- unixFile.assign(tmp);
-
- Glib::ustring contentType;
- bool uncertain;
- contentType = Gio::content_type_guess(unixFile, std::string(""),
- uncertain);
-
- Bool success = FALSE;
- PseudoAppMgr appMgr;
- PseudoApp app;
-
- /*
- * H'okay. So we're looking up icons, yeah?
- *
- * 1. If given a URI for an XDG desktop entry file, search for an icon based
- * on its Icon key.
- * 2. If given a pseudo app URI, as identified by appMgr, use the special
- * icon associated with said pseudo app.
- * 3. If given a folder, try going with "folder" (per icon-naming-spec).
- * 4. Else fall back to searching our theme for an icon based on MIME/
- * content type.
- */
-
- if (g_str_has_suffix(unixFile.c_str(), ".desktop")) {
- Glib::RefPtr<Gio::DesktopAppInfo> desktopFileInfo;
-
- desktopFileInfo = Gio::DesktopAppInfo::create_from_filename(unixFile);
- if (desktopFileInfo) {
- friendlyName = desktopFileInfo->get_name();
- GHIX11IconGetIconsForDesktopFile(unixFile.c_str(), iconList);
- success = TRUE;
- }
- } else if (appMgr.GetAppByUri(uriSansQuery, app)) {
- friendlyName = app.symbolicName;
- GHIX11IconGetIconsByName(app.iconName.c_str(), iconList);
- success = TRUE;
- } else if (Glib::file_test(unixFile, Glib::FILE_TEST_IS_DIR)) {
- friendlyName = Glib::filename_display_basename(unixFile);
- GHIX11IconGetIconsByName("folder", iconList);
- success = TRUE;
- } else {
- friendlyName = Glib::filename_display_basename(unixFile);
- size_t i = 0;
- while ((i = contentType.find('/', i)) != contentType.npos) {
- contentType.replace(i, 1, "-");
- }
- GHIX11IconGetIconsByName(contentType.c_str(), iconList);
- success = TRUE;
- }
-
- uriFreeUriMembersA(&uri);
- return success;
- } else {
- uriFreeUriMembersA(&uri);
- Debug("Binary URI %s does not have a 'file' scheme\n", pathURIUtf8);
- return FALSE;
- }
- } else {
- uriFreeUriMembersA(&uri);
- return FALSE;
- }
-
- return FALSE;
-}
-
-
-#if !defined(OPEN_VM_TOOLS)
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformGetBinaryHandlers --
- *
- * Get the list of filetypes and URL protocols supported by a binary
- * (application). We're passed an app path in URI format, and we find
- * the app info by looking up the path in GHIPlatform->appsByExecutable.
- * Once we find it, we can retrieve info on the app from the .desktop file.
- *
- * Results:
- * A Filetype list of the handlers.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-const FileTypeList&
-GHIPlatformGetBinaryHandlers(GHIPlatform *ghip, // IN: platform-specific state
- const char *pathUtf8) // IN: full path to the executable
-{
- return sEmptyFileTypeList;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformOpenStartMenuTree --
- *
- * Get start menu item count for a given root. This function should be
- * called before iterating through the menu item subtree.
- * To start at the root of the start menu, pass in "" for the root.
- *
- * The output 'buf' is a string holding two numbers separated by a space:
- * 1. A handle ID for this menu tree iterator.
- * 2. A count of the items in this iterator.
- *
- * Results:
- * TRUE if we were able to get the count successfully
- * FALSE otherwise
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHIPlatformOpenStartMenuTree(GHIPlatform *ghip, // IN: platform-specific state
- const char *rootUtf8, // IN: root of the tree
- uint32 flags, // IN: flags
- uint32 &handle, // OUT: menu handle
- uint32 &numItems) // OUT: number of items
-{
- Bool success = FALSE;
-
-#ifdef REDIST_GMENU
- std::pair<uint32,uint32> descriptor;
- if (ghip->menuItemManager->OpenMenuTree(rootUtf8, &descriptor)) {
- handle = descriptor.first;
- numItems = descriptor.second;
- success = TRUE;
- }
-#endif
-
- return success;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformGetStartMenuItem --
- *
- * Get start menu item at a given index. This function should be called
- * in the loop to get all items for a menu sub-tree.
- * If there are no more items, the function will return FALSE.
- *
- * Results:
- * TRUE if there's an item at a given index, FALSE otherwise.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHIPlatformGetStartMenuItem(GHIPlatform *ghip, // IN: platform-specific state
- uint32 handle, // IN: tree handle
- uint32 itemIndex, // IN: the index of the item in the tree
- Bool &isSubmenu, // OUT: True if this item is a submenu
- utf::string &menuPath, // OUT: Path to the submenu (if this item is a submenu)
- utf::string &itemPathURI, // OUT: URI for the item (empty if this is a submenu)
- utf::string &itemName) // OUT: The name/label for the item
-{
- Bool success = FALSE;
-
-#ifdef REDIST_GMENU
- const MenuItem* menuItem;
- const Glib::ustring* path;
-
- if (ghip->menuItemManager->GetMenuItem(handle, itemIndex, &menuItem, &path)) {
- Glib::ustring key = *path + "/" + menuItem->key;
- menuPath = key;
-
- isSubmenu = menuItem->isFolder;
-
- itemPathURI = menuItem->execPath.c_str();
- itemName = menuItem->displayName.c_str();
- success = TRUE;
- }
-#endif
-
- return success;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformCloseStartMenu --
- *
- * Free all memory associated with this start menu tree and cleanup.
- *
- * Results:
- * TRUE if the handle is valid
- * FALSE otherwise
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHIPlatformCloseStartMenuTree(GHIPlatform *ghip, // IN: platform-specific state
- uint32 handle) // IN: handle to the tree to be closed
-{
-#ifdef REDIST_GMENU
- return ghip->menuItemManager->CloseMenuTree(handle);
-#else
- return FALSE;
-#endif
-}
-#endif // OPEN_VM_TOOLS
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GHIPlatformMenuItemToURI --
- *
- * Returns the URI that would be used to launch a particular GHI menu item
- *
- * Results:
- * Newly allocated URI string
- *
- * Side effects:
- * Allocates memory for the URI.
- *
- *-----------------------------------------------------------------------------
- */
-
-static char *
-GHIPlatformMenuItemToURI(GHIPlatform *ghip, // IN
- GHIMenuItem *gmi) // IN
-{
- gchar **argv;
- gint argc;
-
- char *ctmp;
- UriQueryListA *queryItems;
- int i;
- int err;
- gboolean res;
- int nchars;
- char *uriString;
- char *queryString;
-
- ASSERT(ghip);
- ASSERT(gmi);
-
- ctmp = g_key_file_get_string(gmi->keyfile, G_KEY_FILE_DESKTOP_GROUP,
- G_KEY_FILE_DESKTOP_KEY_EXEC, NULL);
-
- res = g_shell_parse_argv(ctmp, &argc, &argv, NULL);
- g_free(ctmp);
- if (!res) {
- return NULL;
- }
-
- queryItems = (UriQueryListA *) alloca((argc + 1) * sizeof *queryItems);
-
- for (i = 0; i < (argc - 1); i++) {
- queryItems[i].key = "argv[]";
- queryItems[i].value = argv[i + 1];
- queryItems[i].next = &queryItems[i + 1];
- }
- queryItems[i].key = "DesktopEntry";
- queryItems[i].value = gmi->keyfilePath;
- queryItems[i].next = NULL;
-
- /*
- * 10 + 3 * len is the formula recommended by uriparser for the maximum URI string
- * length.
- */
- uriString = (char *) alloca(10 + 3 * strlen(gmi->exepath));
- if (uriUnixFilenameToUriStringA(gmi->exepath, uriString)) {
- g_strfreev(argv);
- return NULL;
- }
- if (uriComposeQueryCharsRequiredA(queryItems, &nchars) != URI_SUCCESS) {
- g_strfreev(argv);
- return NULL;
- }
- queryString = (char *) alloca(nchars + 1);
- err = uriComposeQueryA(queryString, queryItems, nchars + 1, &i);
- g_strfreev(argv);
- if (err != URI_SUCCESS) {
- return NULL;
- }
-
- return g_strdup_printf("%s?%s", uriString, queryString);
-}
-
-
-#if 0 // REMOVE AFTER IMPLEMENTING GHIPlatformShellAction
-/*
- *-----------------------------------------------------------------------------
- *
- * GHIPlatformFindHGFSShare --
- *
- * Finds the filesystem path to a particular HGFS sharename
- *
- * Results:
- * Newly heap-allocated path to the top of the specified share.
- *
- * Side effects:
- * Allocates memory for the return value.
- *
- *-----------------------------------------------------------------------------
- */
-
-static char *
-GHIPlatformFindHGFSShare(GHIPlatform *ghip, // IN
- const UriTextRangeA *sharename) // IN
-{
- FILE *fh;
- struct mntent *ment;
-
- fh = Posix_Setmntent(_PATH_MOUNTED, "r");
- if (!fh) {
- return NULL;
- }
-
- while ((ment = Posix_Getmntent(fh))) {
- char *fsSharename;
- if (strcmp(ment->mnt_type, "hgfs") && strcmp(ment->mnt_type, "vmhgfs")) {
- continue;
- }
-
- if (!StrUtil_StartsWith(ment->mnt_fsname, ".host:")) {
- Warning("HGFS filesystem has an fsname of \"%s\" rather than \".host:...\"\n",
- ment->mnt_fsname);
- continue;
- }
-
- if (ment->mnt_fsname[strlen(".host:")] == '/') {
- fsSharename = ment->mnt_fsname + strlen(".host:/");
- } else {
- fsSharename = ment->mnt_fsname + strlen(".host:");
- }
-
- /*
- * XXX this function's logic could be improved substantially to do deeper matching
- * (e.g. if someone has .host:/foo/bar mounted, but nothing else, and is looking to
- * open the document share://foo/bar/baz). Don't know if HGFS allows that, but
- * that'd require passing in the whole URI rather than just the sharename.
- */
- if (URI_TEXTRANGE_EQUAL(*sharename, fsSharename)) {
- char *retval = g_strdup(ment->mnt_dir);
-
- fclose(fh);
-
- return retval;
- } else if (fsSharename == '\0') {
- /*
- * This is a mount of the toplevel HGFS directory, so we know it should work.
- */
- char *retval = g_strdup_printf("%s/%.*s",
- ment->mnt_dir,
- (int)(sharename->afterLast - sharename->first),
- sharename->first);
- fclose(fh);
- return retval;
- }
- }
- fclose(fh);
-
- return NULL;
-}
-#endif // REMOVE AFTER IMPLEMENTING GHIPlatformShellAction
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformShellOpen --
- *
- * Open the specified file with the default shell handler (ShellExecute).
- * Note that the file path may be either a URI (originated with
- * Tools >= NNNNN), or a regular path (originated with Tools < NNNNN).
- *
- * Results:
- * TRUE if successful, FALSE otherwise.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHIPlatformShellOpen(GHIPlatform *ghip, // IN
- const char *fileUtf8) // IN
-{
- ASSERT(ghip);
- ASSERT(fileUtf8);
-
- Debug("%s: file: '%s'\n", __FUNCTION__, fileUtf8);
-
- UriParserStateA upState;
- UriUriA uri;
-
- memset(&upState, 0, sizeof upState);
- memset(&uri, 0, sizeof uri);
- upState.uri = &uri;
-
- if (uriParseUriA(&upState, fileUtf8) == URI_SUCCESS &&
- URI_TEXTRANGE_EQUAL(uri.scheme, "file")) {
- Bool success = FALSE;
-
- gchar* tmp = (gchar*)g_alloca(strlen(fileUtf8) + 1);
- uriUriStringToUnixFilenameA(fileUtf8, tmp);
-
- Glib::ustring unixFile;
- unixFile.assign(tmp);
-
- Glib::ustring contentType;
- bool uncertain;
- contentType = Gio::content_type_guess(unixFile, std::string(""), uncertain);
-
- if (contentType == "application/x-desktop") {
- GDesktopAppInfo* dappinfo;
- dappinfo = g_desktop_app_info_new_from_filename(unixFile.c_str());
- if (dappinfo) {
- GAppInfo *appinfo = (GAppInfo*)G_APP_INFO(dappinfo);
- success = AppInfoLaunchEnv(ghip, appinfo);
- g_object_unref(dappinfo);
- }
- } else if (Glib::file_test(unixFile, Glib::FILE_TEST_IS_REGULAR) &&
- Glib::file_test(unixFile, Glib::FILE_TEST_IS_EXECUTABLE)) {
- std::vector<Glib::ustring> argv;
- argv.push_back(unixFile);
- try {
- Glib::spawn_async("" /* inherit cwd */, argv, ghip->nativeEnviron, (Glib::SpawnFlags) 0);
- success = TRUE;
- } catch(Glib::SpawnError& e) {
- g_warning("%s: %s: %s\n", __FUNCTION__, unixFile.c_str(), e.what().c_str());
- }
- } else {
- std::vector<Glib::ustring> argv;
- Glib::ustring de = Xdg_DetectDesktopEnv();
- // XXX Really we should just use xdg-open exclusively, but xdg-open
- // as shipped with xdg-utils 1.0.2 is broken. It is fixed
- // in portland CVS, but we need to import into modsource and
- // redistribute with Tools in order to guarantee a working version.
- if (de == "GNOME") {
- argv.push_back("gnome-open");
- } else if (de == "KDE") {
- argv.push_back("kde-open");
- } else {
- argv.push_back("xdg-open");
- }
- argv.push_back(unixFile);
- try {
- Glib::spawn_async("", argv, ghip->nativeEnviron, Glib::SPAWN_SEARCH_PATH);
- success = TRUE;
- } catch(Glib::SpawnError& e) {
- g_warning("%s: %s: %s\n", __FUNCTION__, unixFile.c_str(), e.what().c_str());
- }
- }
-
- return success;
- }
-
- return FALSE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformShellAction --
- * Perform the specified shell action with the optional target and
- * locations arguments. Note that the target may be either a URI
- * (originated with Tools >= NNNNN), or a regular path (originated with
- * Tools < NNNNN).
- * See the comment at ghIntegration.c::GHITcloShellAction for information
- * on the command format and supported actions.
- *
- * Results:
- * TRUE if successful, FALSE otherwise.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHIPlatformShellAction(GHIPlatform *ghip, // IN: platform-specific state
- const char *actionURI, // IN
- const char *targetURI, // IN
- const char **locations, // IN
- int numLocations) // IN
-{
- /*
- * TODO: implement the shell action execution.
- * The GHIPlatformShellUrlOpen() below is left for reference, but is not
- * used right now. Its functionality should be integrated here.
- */
- ASSERT(ghip);
- ASSERT(actionURI);
- ASSERT(targetURI);
-
- Debug("%s not implemented yet.\n", __FUNCTION__);
-
- return FALSE;
-}
-
-
-#if 0 // REMOVE AFTER IMPLEMENTING GHIPlatformShellAction
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformShellUrlOpen --
- *
- * Run ShellExecute on a given file.
- *
- * Results:
- * TRUE if success, FALSE otherwise.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHIPlatformShellUrlOpen(GHIPlatform *ghip, // IN: platform-specific state
- const char *fileUtf8, // IN: command/file
- const char *actionUtf8) // IN: action
-{
-#ifdef GTK2
- char **fileArgv = NULL;
- int fileArgc = 0;
- char *fileDotDesktop = NULL;
- char **actionArgv = NULL;
- int actionArgc = 0;
- char *actionDotDesktop = NULL;
- char **fullArgv = NULL;
- int fullArgc = 0;
-
- Bool retval = FALSE;
-
- ASSERT(ghip);
-
- if (!GHIPlatformURIToArgs(ghip, fileUtf8, &fileArgv, &fileArgc,
- &fileDotDesktop)) {
- Debug("Parsing URI %s failed\n", fileUtf8);
- return FALSE;
- }
-
- if (actionUtf8 && !GHIPlatformURIToArgs(ghip, actionUtf8, &actionArgv, &actionArgc,
- &actionDotDesktop)) {
- Debug("Parsing action URI %s failed\n", actionUtf8);
- g_strfreev(fileArgv);
- g_free(fileDotDesktop);
- return FALSE;
- }
-
- if (GHIPlatformCombineArgs(ghip,
- fileUtf8, &fileArgv, &fileArgc, fileDotDesktop,
- actionUtf8, &actionArgv, &actionArgc, actionDotDesktop,
- &fullArgv, &fullArgc)) {
- retval = g_spawn_async(NULL, fullArgv, NULL,
- G_SPAWN_SEARCH_PATH |
- G_SPAWN_STDOUT_TO_DEV_NULL |
- G_SPAWN_STDERR_TO_DEV_NULL,
- NULL, NULL, NULL, NULL);
- }
-
- g_strfreev(fileArgv);
- g_free(fileDotDesktop);
- g_strfreev(actionArgv);
- g_free(actionDotDesktop);
- g_strfreev(fullArgv);
-
- return retval;
-#else // !GTK2
- return FALSE;
-#endif // GTK2
-}
-#endif // REMOVE AFTER IMPLEMENTING GHIPlatformShellAction
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformSetGuestHandler --
- *
- * Set the handler for the specified filetype (or URL protocol) to the
- * given value.
- *
- * Results:
- * TRUE if successful, FALSE otherwise.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHIPlatformSetGuestHandler(GHIPlatform *ghip, // IN: platform-specific state
- const char *suffix, // IN/OPT: suffix
- const char *mimeType, // IN/OPT: MIME Type
- const char *UTI, // IN/OPT: UTI
- const char *actionURI, // IN:
- const char *targetURI) // IN:
-{
- ASSERT(ghip);
-
- return FALSE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformRestoreDefaultGuestHandler --
- *
- * Restore the handler for a given type to the value in use before any
- * changes by tools.
- *
- * Results:
- * TRUE if successful, FALSE otherwise.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHIPlatformRestoreDefaultGuestHandler(GHIPlatform *ghip, // IN: platform-specific state
- const char *suffix, // IN/OPT: Suffix
- const char *mimetype, // IN/OPT: MIME Type
- const char *UTI) // IN/OPT: UTI
-{
- ASSERT(ghip);
-
- return FALSE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHIPlatformSetOutlookTempFolder --
- *
- * Set the temporary folder used by Microsoft Outlook to store attachments
- * opened by the user.
- *
- * XXX While we probably won't ever need to implement this for Linux, we
- * still the definition of this function in the X11 back-end.
- *
- * Results:
- * TRUE if successful, FALSE otherwise.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHIPlatformSetOutlookTempFolder(GHIPlatform *ghip, // IN: platform-specific state
- const char *targetURI) // IN: Target URI
-{
- ASSERT(ghip);
- ASSERT(targetURI);
-
- return FALSE;
-}
-
-
-/* @brief Send a mouse or keyboard event to a tray icon.
- *
- * @param[in] ghip Pointer to platform-specific GHI data.
- *
- * @retval TRUE Operation Succeeded.
- * @retval FALSE Operation Failed.
- */
-
-Bool
-GHIPlatformTrayIconSendEvent(GHIPlatform *ghip,
- const char *iconID,
- uint32 event,
- uint32 x,
- uint32 y)
-{
- ASSERT(ghip);
- ASSERT(iconID);
- return FALSE;
-}
-
-/* @brief Start sending tray icon updates to the VMX.
- *
- * @param[in] ghip Pointer to platform-specific GHI data.
- *
- * @retval TRUE Operation Succeeded.
- * @retval FALSE Operation Failed.
- */
-
-Bool
-GHIPlatformTrayIconStartUpdates(GHIPlatform *ghip)
-{
- ASSERT(ghip);
- return FALSE;
-}
-
-/* @brief Stop sending tray icon updates to the VMX.
- *
- * @param[in] ghip Pointer to platform-specific GHI data.
- *
- * @retval TRUE Operation Succeeded.
- * @retval FALSE Operation Failed.
- */
-
-Bool
-GHIPlatformTrayIconStopUpdates(GHIPlatform *ghip)
-{
- ASSERT(ghip);
- return FALSE;
-}
-
-/* @brief Set a window to be focused.
- *
- * @param[in] ghip Pointer to platform-specific GHI data.
- * @param[in] xdrs Pointer to serialized data from the host.
- *
- * @retval TRUE Operation Succeeded.
- * @retval FALSE Operation Failed.
- */
-
-Bool
-GHIPlatformSetFocusedWindow(GHIPlatform *ghip,
- int32 windowId)
-{
- ASSERT(ghip);
- return FALSE;
-}
-
-
-/**
- * @brief Get the hash (or timestamp) of information returned by
- * GHIPlatformGetBinaryInfo.
- *
- * @param[in] ghip Pointer to platform-specific GHI data.
- * @param[in] request Request containing which executable to get the hash for.
- * @param[out] reply Reply to be filled with the hash.
- *
- * @retval TRUE Operation succeeded.
- * @retval FALSE Operation failed.
- */
-
-Bool GHIPlatformGetExecInfoHash(GHIPlatform *ghip,
- const char *execPath,
- char **execInfoHash)
-{
- ASSERT(ghip);
- ASSERT(execPath);
- ASSERT(execInfoHash);
-
- return FALSE;
-}
-
-
-/*
- ******************************************************************************
- * GHIX11FindDesktopUriByExec -- */ /**
- *
- * Given an executable path, attempt to generate an "execUri" associated with a
- * corresponding .desktop file.
- *
- * @sa GHIX11_FindDesktopUriByExec
- *
- * @note Returned pointer belongs to the GHI module. Caller must not free it.
- *
- * @param[in] ghip GHI platform-specific context.
- * @param[in] execPath Input binary path. May be absolute or relative.
- *
- * @return Pointer to a URI string on success, NULL on failure.
- *
- ******************************************************************************
- */
-
-const gchar *
-GHIX11FindDesktopUriByExec(GHIPlatform *ghip,
- const char *exec)
-{
- char pathbuf[MAXPATHLEN];
- gchar *pathname = NULL;
- gchar *uri = NULL;
- GHIMenuItem *gmi;
- gboolean fudged = FALSE;
- gboolean basenamed = FALSE;
-
- ASSERT(ghip);
- ASSERT(exec);
-
- /*
- * XXX This is not shippable. This is to be addressed by milestone 3 with
- * the improved "fuzzy logic for UNITY_RPC_GET_WINDOW_PATH" deliverable.
- */
-
- return NULL;
-
- /*
- * Check our hash table first. Negative entries are also cached.
- */
- if (g_hash_table_lookup_extended(ghip->appsByWindowExecutable,
- exec, NULL, (gpointer*)&uri)) {
- return uri;
- }
-
- /*
- * Okay, execPath may be absolute or relative.
- *
- * We'll search for a matching .desktop entry using the following methods:
- *
- * 1. Use absolute path of exec.
- * 2. Use absolute path of basename of exec. (Resolves /opt/Adobe/Reader9/
- * Reader/intellinux/bin/acroread to /usr/bin/acroread.)
- * 3. Consult whitelist of known applications and guess at possible
- * launchers. (firefox-bin => firefox, soffice.bin => ooffice.)
- */
-
- /*
- * Attempt #1: Start with unmodified input.
- */
- Str_Strcpy(pathbuf, exec, sizeof pathbuf);
-
-tryagain:
- g_free(pathname); // Placed here rather than at each goto. I'm lazy.
-
- pathname = g_find_program_in_path(pathbuf);
- if (pathname) {
- gmi = (GHIMenuItem*)g_hash_table_lookup(ghip->appsByExecutable, pathname);
- if (gmi) {
- uri = GHIPlatformMenuItemToURI(ghip, gmi);
- }
- }
-
- if (!uri) {
- /*
- * Attempt #2: Take the basename of exec.
- */
- if (!basenamed) {
- char tmpbuf[MAXPATHLEN];
- char *ctmp;
-
- basenamed = TRUE;
-
- /* basename(3) may modify the input buffer, so make a temporary copy. */
- Str_Strcpy(tmpbuf, pathbuf, sizeof tmpbuf);
- ctmp = basename(tmpbuf);
- if (ctmp != NULL) {
- Str_Strcpy(pathbuf, ctmp, sizeof pathbuf);
- goto tryagain;
- }
- }
-
- /*
- * Attempt #3: Get our whitelist on.
- */
- if (!fudged) {
- static struct {
- const gchar *pattern;
- const gchar *exec;
- } fudgePatterns[] = {
- /*
- * XXX Worth compiling once? Consider placing in an external filter
- * file to allow users to update it themselves easily.
- */
- { "*firefox*-bin", "firefox" },
- { "*thunderbird*-bin", "thunderbird" },
- { "*soffice.bin", "ooffice" }
- };
- unsigned int i;
-
- fudged = TRUE;
-
- for (i = 0; i < ARRAYSIZE(fudgePatterns); i++) {
- if (g_pattern_match_simple(fudgePatterns[i].pattern,
- pathbuf)) {
- Str_Strcpy(pathbuf, fudgePatterns[i].exec, sizeof pathbuf);
- goto tryagain;
- }
- }
- }
- }
-
- g_free(pathname);
-
- /*
- * Cache the result, even if it was negative.
- */
- g_hash_table_insert(ghip->appsByWindowExecutable, g_strdup(exec), uri);
-
- return uri;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * AppInfoLaunchEnv --
- *
- * Wrapper around g_app_info_launch which takes a custom environment into
- * account.
- *
- * GHI/X11 should spawn applications using ghip->nativeEnviron, but
- * g_app_info_launch doesn't taken a custom environment as a parameter.
- * Rather than reimplement that function, we work around it by doing the
- * following:
- *
- * Parent:
- * 1. Fork a child process.
- * 2. Block until child terminates, returning true if the child exited
- * with an exit code of 0.
- *
- * Child:
- * 1. Flush the environment and build a new one from nativeEnviron.
- * 2. Spawn desired application with g_app_info_launch.
- * 3. Exit with 0 if spawn was successful, otherwise 1.
- *
- * Results:
- * Returns true if launch succeeded, false otherwise.
- *
- * Side effects:
- * Creates a child process and blocks until the child exits. Child lasts
- * only as long as it takes to call g_app_info_launch.
- *
- *-----------------------------------------------------------------------------
- */
-
-static bool
-AppInfoLaunchEnv(GHIPlatform* ghip, // IN
- GAppInfo* appInfo) // IN
-{
- bool success = false;
-
- pid_t myPid = fork();
- switch (myPid) {
- case -1:
- /* Error. */
- g_warning("%s: fork: %s\n", __FUNCTION__, strerror(errno));
- break;
-
- case 0:
- /* Child: Exit with _exit() so as to not trigger any atexit() routines. */
- {
- if (clearenv() == 0) {
- std::vector<Glib::ustring>::iterator envp;
- for (envp = ghip->nativeEnviron.begin();
- envp != ghip->nativeEnviron.end();
- ++envp) {
- /*
- * The string passed to putenv() becomes part of the environment --
- * it isn't copied. That's fine, though, because we're running in
- * the context of a very short-lived wrapper process.
- */
- if (putenv((char*)envp->c_str()) != 0) {
- g_warning("%s: failed to restore native environment\n", __FUNCTION__);
- _exit(1);
- }
- }
- success = g_app_info_launch(appInfo, NULL, NULL, NULL);
- }
- _exit(success == true ? 0 : 1);
- }
- break;
-
- default:
- /* Parent: Hang out until our child terminates. */
- {
- int status = 0;
- int ret = -1;
- while (1) {
- ret = waitpid(myPid, &status, 0);
- if ((ret == -1 && errno != EINTR) ||
- (ret == myPid && (WIFEXITED(status) || WIFSIGNALED(status)))) {
- break;
- }
- }
- success = (ret == myPid) && WIFEXITED(status) && WEXITSTATUS(status) == 0;
- }
- }
-
- return success;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * OnMenusChanged --
- *
- * Signal handler for updates to launch or fixed menus.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Calls transport's launchMenuChange callback, if set.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-OnMenusChanged(GHIPlatform *ghip) // IN
-{
- if (ghip->hostCallbacks.launchMenuChange) {
- std::vector<const char *> folderKeysChanged;
- folderKeysChanged.push_back(UNITY_START_MENU_LAUNCH_FOLDER);
- folderKeysChanged.push_back(UNITY_START_MENU_FIXED_FOLDER);
- ghip->hostCallbacks.launchMenuChange(folderKeysChanged.size(),
- &folderKeysChanged[0]);
- }
-}
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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.
- *
- *********************************************************/
-
-/*
- * pseudoAppMgr.cc --
- *
- * Manages "pseudo-applications" for special menu items, such as
- * directories for which we wish to display custom menu item icons or
- * executables which do not have regular menu items.
- *
- * Pseudo apps are assigned well-known IDs (AppId, compile-time), and
- * are associated with URIs at runtime. (Example: A user's Desktop
- * folder has a compile-time AppId of PSEUDO_APP_DESKTOP with a likely
- * runtime URI of $HOME/Desktop.)
- *
- * URIs may be influenced by environment variables or simply the existence
- * of a program in the user's search path.
- */
-
-
-#include <glibmm.h>
-#include <glib/gi18n.h>
-#include <stdexcept>
-
-#include "vmware/tools/ghi/pseudoAppMgr.hh"
-
-extern "C" {
-#include "vmware.h"
-};
-
-namespace vmware {
-namespace tools {
-namespace ghi {
-
-
-/*
- * PseudoApps indexed by URI (ex: file:///home/user/Desktop).
- */
-std::tr1::unordered_map<Glib::ustring,PseudoApp,
- std::tr1::hash<std::string> > PseudoAppMgr::sApps;
-
-/*
- * PseudoApp URIs indexed by app ID.
- */
-std::vector<Glib::ustring> PseudoAppMgr::sUris;
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * PseudoAppMgr::PseudoAppMgr --
- *
- * Populates sApps.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-PseudoAppMgr::PseudoAppMgr()
-{
- static bool initialized = false;
-
- if (!initialized) {
- InitUriVector();
- InitAppMap();
- initialized = true;
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * PseudoAppMgr::GetAppByAppId --
- *
- * Search for pseudo app by AppId.
- *
- * Results:
- * Populates app.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-PseudoAppMgr::GetAppByAppId(AppId id, // IN
- PseudoApp& app) // OUT
- const
-{
- if (id < PSEUDO_APP_HOME || id >= PSEUDO_APP_NAPPS) {
- throw std::logic_error("Invalid PseudoApp identifier");
- }
-
- app = sApps[sUris[id]];
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * PseudoAppMgr::LookupPath --
- *
- * Search for pseudo app by URI.
- *
- * Results:
- * Returns true and populates app on success.
- * Returns false on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-bool
-PseudoAppMgr::GetAppByUri(const Glib::ustring& uri, // IN
- PseudoApp& app) // OUT
- const
-{
- if (sApps.find(uri) != sApps.end()) {
- app = sApps[uri];
- return true;
- }
-
- return false;
-}
-
-
-/*
- ******************************************************************************
- * BEGIN private methods.
- */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * PseudoAppMgr::InitAppMap --
- *
- * Populate application map based on static data.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Populates sApps.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-PseudoAppMgr::InitAppMap()
-{
- static const struct {
- const char* symbolicName;
- const char* iconName;
- } initTable[] = {
- { "Home Folder", "user-home" }, // PSEUDO_APP_HOME
- { "Bookmarks", "user-bookmarks" }, // ..._BOOKMARKS
- { "Desktop", "user-desktop" }, // ..._DESKTOP
- { "Documents", "folder" }, // ..._DOCUMENTS
- { "Download", "folder" }, // ..._DOWNLOAD
- { "Music", "folder" }, // ..._MUSIC
- { "Pictures", "folder" }, // ..._PICTURES
- { "Connect to Server...", "applications-internet" }, // ..._GNOME_CONNECT
- };
- size_t idx;
-
- ASSERT_ON_COMPILE(ARRAYSIZE(initTable) == PSEUDO_APP_NAPPS);
-
- for (idx = 0; idx < ARRAYSIZE(initTable); idx++) {
- Glib::ustring uri = sUris[idx];
- if (!uri.empty()) {
- sApps[uri].uri = uri;
- /*
- * gettext lookup against xdg-user-dirs is purely opportunistic. Standalone
- * apps (likely) won't exist there, but to keep the loop logic simple, they
- * aren't excluded from said lookup.
- */
- sApps[uri].symbolicName = g_dgettext("xdg-user-dirs",
- initTable[idx].symbolicName);
- sApps[uri].iconName = initTable[idx].iconName;
- }
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * PseudoAppMgr::InitUriVector --
- *
- * Populate sUris based on runtime environment. See xdg-user-dirs for
- * more details.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Populates sUris.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-PseudoAppMgr::InitUriVector()
-{
- sUris.resize(PSEUDO_APP_NAPPS);
-
- try {
- sUris[PSEUDO_APP_HOME] = Glib::filename_to_uri(Glib::get_home_dir());
-
- std::vector<Glib::ustring> components;
- components.push_back(Glib::get_home_dir());
- components.push_back(".gtk-bookmarks");
- sUris[PSEUDO_APP_BOOKMARKS] =
- Glib::filename_to_uri(Glib::build_filename(components));
-
-#define MAP_GUSER_PSEUDO(gUserDir, pAppId) { \
- Glib::ustring dir = Glib::get_user_special_dir((gUserDir)); \
- if (!dir.empty()) { \
- sUris[(pAppId)] = Glib::filename_to_uri(dir); \
- } \
-}
-
- MAP_GUSER_PSEUDO(G_USER_DIRECTORY_DESKTOP, PSEUDO_APP_DESKTOP);
- MAP_GUSER_PSEUDO(G_USER_DIRECTORY_DOCUMENTS, PSEUDO_APP_DOCUMENTS);
- MAP_GUSER_PSEUDO(G_USER_DIRECTORY_DOWNLOAD, PSEUDO_APP_DOWNLOAD);
- MAP_GUSER_PSEUDO(G_USER_DIRECTORY_MUSIC, PSEUDO_APP_MUSIC);
- MAP_GUSER_PSEUDO(G_USER_DIRECTORY_PICTURES, PSEUDO_APP_PICTURES);
-
- Glib::ustring connectPath = Glib::find_program_in_path("nautilus-connect-server");
- if (!connectPath.empty()) {
- sUris[PSEUDO_APP_GNOME_CONNECT] = Glib::filename_to_uri(connectPath);
- }
- } catch (std::exception& e) {
- g_warning("%s: Caught exception while learning XDG directories: %s\n",
- __func__, e.what());
- }
-}
-
-
-/*
- * END private methods.
- ******************************************************************************
- */
-
-} /* namespace ghi */ } /* namespace tools */ } /* namespace vmware */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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.
- *
- *********************************************************/
-
-/*
- * pseudoAppMgr.hh --
- *
- * Manages "pseudo-applications" for special menu items, such as
- * directories for which we wish to display custom menu item icons.
- */
-
-#ifndef _GHI_PSEUDOAPPMGR_HH_
-#define _GHI_PSEUDOAPPMGR_HH_
-
-#define INCLUDE_ALLOW_USERLEVEL
-#include "includeCheck.h"
-
-#include <glibmm.h>
-#include <tr1/unordered_map>
-
-namespace vmware {
-namespace tools {
-namespace ghi {
-
-struct PseudoApp {
- Glib::ustring uri; // file:///home/foo/Documents
- Glib::ustring symbolicName; // Documents or Dokumente
- Glib::ustring iconName; // see icon-naming-spec
-};
-
-class PseudoAppMgr {
-public:
- // WARNING: Don't change these values w/o visiting the assignment code in
- // pseudoAppMgr.cc.
- enum AppId {
- // Defined entirely by GHI.
- PSEUDO_APP_HOME,
- PSEUDO_APP_BOOKMARKS,
- // Based on GLib GUserDirectory.
- PSEUDO_APP_DESKTOP,
- PSEUDO_APP_DOCUMENTS,
- PSEUDO_APP_DOWNLOAD,
- PSEUDO_APP_MUSIC,
- PSEUDO_APP_PICTURES,
- // executables sans .desktop files
- PSEUDO_APP_GNOME_CONNECT, // gnome-connect-server
- // Placeholder.
- PSEUDO_APP_NAPPS
- };
-
- PseudoAppMgr();
-
- // XXX I don't like the asymmetric return/pass-by-reference semantics.
- void GetAppByAppId(AppId id, PseudoApp& app) const;
- bool GetAppByUri(const Glib::ustring& uri, PseudoApp& app) const;
-private:
- void InitAppMap();
- void InitUriVector();
-
- // Indexed by URI.
- static std::tr1::unordered_map<Glib::ustring,PseudoApp,
- std::tr1::hash<std::string> > sApps;
- // AppId => URI.
- static std::vector<Glib::ustring> sUris;
-};
-
-} /* namespace ghi */ } /* namespace tools */ } /* namespace vmware */
-
-#endif // ifndef _GHI_PSEUDOAPPMGR_HH_
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * ghiCommonDefines.h --
- *
- * Common definitions of maximum sizes/lengths for data used in
- * guest/host integration XDR serialization.
- */
-
-#ifndef _GHI_COMMON_DEFINES_H_
-#define _GHI_COMMON_DEFINES_H_
-
-#define GHI_MAX_NUM_ACTION_URI_PAIRS 16
-#define GHI_HANDLERS_SUFFIX_MAX_LEN 32
-#define GHI_HANDLERS_MIMETYPE_MAX_LEN 256
-#define GHI_HANDLERS_UTI_MAX_LEN 256
-
-/*
- * The Windows MAX_PATH define specifies that paths may be up to 260 character
- * units in length. To allow for expansion when going to UTF8 we multiply that
- * value by 4 here.
- */
-#define GHI_HANDLERS_ACTIONURI_MAX_PATH 1040
-
-/*
- * Maximum length for a guest app hash value (usually much shorter).
- */
-#define GHI_EXEC_INFO_HASH_MAX_LEN 1024
-
-#endif // ifndef _GHI_COMMON_DEFINES_H_
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * ghiGetBinaryHandlers.x --
- *
- * Definition of the data structures used in the GuestRpc commands to
- * provide information about the types of files a given binary supports.
- */
-
-
-/*
- * Enumerates the different versions of the messages.
- */
-enum GHIBinaryHandlersVersion {
- GHI_BINARY_HANDLERS_V1 = 1
-};
-
-const GHI_HANDLERS_SUFFIX_MAX_LEN = 32;
-const GHI_HANDLERS_MIMETYPE_MAX_LEN = 256;
-const GHI_HANDLERS_UTI_MAX_LEN = 256;
-const GHI_HANDLERS_FRIENDLY_NAME_MAX_LEN = 256;
-const GHI_HANDLERS_MAX_NUM_ICONS = 8;
-const GHI_HANDLERS_VERB_MAX_LEN = 64;
-const GHI_MAX_NUM_ACTION_URI_PAIRS = 16;
-
-/*
- * The Windows MAX_PATH define specifies that paths may be up to 260 character
- * units in length. To allow for expansion when going to UTF8 we multiply that
- * value by 4 here.
- */
-const GHI_HANDLERS_ACTIONURI_MAX_PATH = 1040;
-
-/*
- * Maximum number of filetypes that may be encoded in a single
- * XDR array.
- */
-const GHI_MAX_NUM_BINARY_HANDLERS = 128;
-
-struct GHIBinaryHandlersIconDetails {
- /*
- * The icon dimensions in pixels
- */
- int width;
- int height;
-
- /*
- * A string identifier for this icon that can be used to retrieve
- * the specific pixel data using GHI_GET_ICON_DATA
- */
- string identifier<GHI_HANDLERS_ACTIONURI_MAX_PATH>;
-};
-
-struct GHIBinaryHandlersActionURIPair {
- /*
- * The verb for the action URI (typically something like run or print).
- */
- string verb<GHI_HANDLERS_VERB_MAX_LEN>;
-
- /*
- * The executable path to use when launching the binary with this particular
- * filetype and verb. Some filetypes may require additional or different command line
- * arguments for a given verb that can be encoded here.
- */
- string actionURI<GHI_HANDLERS_ACTIONURI_MAX_PATH>;
-};
-
-struct GHIBinaryHandlersDetails {
- /*
- * The file suffix (including leading period character).
- */
- string suffix<GHI_HANDLERS_SUFFIX_MAX_LEN>;
-
- /*
- * A mimetype - if available.
- */
- string mimetype<GHI_HANDLERS_MIMETYPE_MAX_LEN>;
-
- /*
- * A UTI (universal type identifier) - if available.
- */
- string UTI<GHI_HANDLERS_UTI_MAX_LEN>;
-
- /*
- * A list of the verbs (run, print etc.) and their matching
- * action URIs.
- */
- struct GHIBinaryHandlersActionURIPair actionURIs<GHI_MAX_NUM_ACTION_URI_PAIRS>;
-
- /*
- * A friendly name displayed for this document/filetype.
- */
- string friendlyName<GHI_HANDLERS_FRIENDLY_NAME_MAX_LEN>;
-
- /*
- * A list of the different sized icons for this filetype.
- */
- struct GHIBinaryHandlersIconDetails icons<GHI_HANDLERS_MAX_NUM_ICONS>;
-};
-
-struct GHIBinaryHandlersList {
- struct GHIBinaryHandlersDetails handlers<GHI_MAX_NUM_BINARY_HANDLERS>;
-};
-
-/*
- * This defines the protocol for a 'get.binary.handlers' message. The union allows
- * us to create new versions of the protocol later by creating new values
- * in the GHIBinaryHandlersVersion enumeration, without having to change much of
- * the code calling the (de)serialization functions.
- *
- * Since the union doesn't have a default case, de-serialization will fail
- * if an unknown version is provided on the wire.
- */
-union GHIBinaryHandlers switch (GHIBinaryHandlersVersion ver) {
-case GHI_BINARY_HANDLERS_V1:
- struct GHIBinaryHandlersList *handlersV1;
-};
-
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
-* ghiGetExecInfoHash.x --
-*
-* Definition of the data structures used in the GuestRpc commands to
-* get the hash of information returned by the get.binary.info RPC.
-*/
-
-#include "ghiCommonDefines.h"
-
-/*
-* Enumerates the different versions of the messages.
-*/
-enum GHIGetExecInfoHashVersion {
- GHI_GET_EXEC_INFO_HASH_V1 = 1
-};
-
-/*
-* The structures used for version 1 of the messages.
-*/
-struct GHIGetExecInfoHashRequestV1 {
- /*
- * A string identifier for the executable path.
- */
- string execPath<GHI_HANDLERS_ACTIONURI_MAX_PATH>;
-};
-struct GHIGetExecInfoHashReplyV1 {
- /*
- * A string identifier for the hash.
- */
- string execHash<GHI_EXEC_INFO_HASH_MAX_LEN>;
-};
-
-/*
- * This defines the protocol for 'getExecInfoHash' request and reply messages.
- *
- * The union allows us to introduce new versions of the protocol later by
- * creating new values in the enumeration, without having to change much of
- * the code calling the (de)serialization functions.
- *
- * Since the union doesn't have a default case, de-serialization will fail if
- * an unknown version is provided on the wire.
- */
-union GHIGetExecInfoHashRequest switch (GHIGetExecInfoHashVersion ver) {
-case GHI_GET_EXEC_INFO_HASH_V1:
- struct GHIGetExecInfoHashRequestV1 *requestV1;
-};
-union GHIGetExecInfoHashReply switch (GHIGetExecInfoHashVersion ver) {
-case GHI_GET_EXEC_INFO_HASH_V1:
- struct GHIGetExecInfoHashReplyV1 *replyV1;
-};
-
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * ghiProtocolHandler.x --
- *
- * Definition of the data structures used in the GuestRpc commands to
- * provide information about the guests protocol handlers (applications
- * that are launched when opening URLS).
- */
-
-/*
- * Neither RFC 1630 or 1738 seem to specify an actual maximum, current
- * usage implies that 64 bytes should be sufficient
- */
-const GHI_URL_SCHEME_NAME_MAX_LEN = 64;
-
-/*
- * The Windows MAX_PATH define specifies that paths may be up to 260 character
- * units in length. To allow for expansion when going to UTF8 we multiply that
- * value by 4 here.
- */
-const GHI_PROTOCOL_HANDLER_MAX_PATH = 1040;
-
-/*
- * Maximum number of Protocol Handlers that may be encoded in a single
- * XDR array.
- */
-const GHI_MAX_NUM_PROTOCOL_HANDLERS = 32;
-
-
-struct GHIProtocolHandlerDetails {
- /*
- * The scheme name of a URL is typically, http, ftp, mailto, feed etc.
- */
- string schemeName<GHI_URL_SCHEME_NAME_MAX_LEN>;
-
- /*
- * The action URI is used in conjunction with UNITY_RPC_SHELL_OPEN to
- * instruct the guest to open a specified URL.
- */
- string handlerActionURI<GHI_PROTOCOL_HANDLER_MAX_PATH>;
-
- /*
- * The executable path can be used as a parameter to
- * UNITY_RPC_GET_BINARY_INFO to retrieve additional binary information such
- * as Icon images.
- */
- string executablePath<GHI_PROTOCOL_HANDLER_MAX_PATH>;
-};
-
-struct GHIProtocolHandlerList {
- struct GHIProtocolHandlerDetails handlers<GHI_MAX_NUM_PROTOCOL_HANDLERS>;
-};
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
-* ghiSetFocusedWindow.x --
-*
-* Definition of the data structures used in the GuestRpc commands to
-* set a window to be focused.
-*/
-
-#include "ghiCommonDefines.h"
-
-/*
-* Enumerates the different versions of the messages.
-*/
-enum GHISetFocusedWindowVersion {
- GHI_SET_FOCUSED_WINDOW_V1 = 1
-};
-
-/*
-* The structure used for version 1 of the message.
-*/
-struct GHISetFocusedWindowV1 {
- int windowId;
-};
-
-/*
- * This defines the protocol for a 'setFocusedWindow' message.
- *
- * The union allows us to introduce new versions of the protocol later by
- * creating new values in the enumeration, without having to change much of
- * the code calling the (de)serialization functions.
- *
- * Since the union doesn't have a default case, de-serialization will fail if
- * an unknown version is provided on the wire.
- */
-union GHISetFocusedWindow switch (GHISetFocusedWindowVersion ver) {
-case GHI_SET_FOCUSED_WINDOW_V1:
- struct GHISetFocusedWindowV1 *setFocusedWindowV1;
-};
-
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * ghiSetGuestHandler.x --
- *
- * Definition of the data structures used in the GuestRpc commands to
- * set or restore the handler for a given protocol or file type in the
- * guest.
- */
-
-#include "ghiCommonDefines.h"
-
-/*
- * Enumerates the different versions of the messages.
- */
-enum GHISetGuestHandlerVersion {
- GHI_SET_GUEST_HANDLER_V1 = 1
-};
-
-
-struct GHISetGuestHandlerAction {
- string actionURI<GHI_HANDLERS_ACTIONURI_MAX_PATH>;
- string targetURI<GHI_HANDLERS_ACTIONURI_MAX_PATH>;
-};
-
-struct GHISetGuestHandlerV1 {
- /*
- * The file suffix (including leading period character), or for protocols
- * the handler type ('http', 'ftp' etc).
- */
- string suffix<GHI_HANDLERS_SUFFIX_MAX_LEN>;
-
- /*
- * A mimetype - if available.
- */
- string mimetype<GHI_HANDLERS_MIMETYPE_MAX_LEN>;
-
- /*
- * A UTI (universal type identifier) - if available.
- */
- string UTI<GHI_HANDLERS_UTI_MAX_LEN>;
-
- /*
- * A list of the action URI and target URI's for this handlerType.
- */
- struct GHISetGuestHandlerAction actionURIs<GHI_MAX_NUM_ACTION_URI_PAIRS>;
-};
-
-/*
- * This defines the protocol for a 'setGuestHandler' messages. The union allows
- * us to create new versions of the protocol later by creating new values
- * in the GHISetGuestHandlerVersion enumeration, without having to change much of
- * the code calling the (de)serialization functions.
- *
- * Since the union doesn't have a default case, de-serialization will fail
- * if an unknown version is provided on the wire.
- */
-union GHISetGuestHandler switch (GHISetGuestHandlerVersion ver) {
-case GHI_SET_GUEST_HANDLER_V1:
- struct GHISetGuestHandlerV1 *guestHandlerV1;
-};
-
-
-struct GHIRestoreDefaultGuestHandlerV1 {
- /*
- * The file suffix (including leading period character), or for protocols
- * the handler type ('http', 'ftp' etc).
- */
- string suffix<GHI_HANDLERS_SUFFIX_MAX_LEN>;
-
- /*
- * A mimetype - if available.
- */
- string mimetype<GHI_HANDLERS_MIMETYPE_MAX_LEN>;
-
- /*
- * A UTI (universal type identifier) - if available.
- */
- string UTI<GHI_HANDLERS_UTI_MAX_LEN>;
-};
-
-union GHIRestoreDefaultGuestHandler switch (GHISetGuestHandlerVersion ver) {
-case GHI_SET_GUEST_HANDLER_V1:
- struct GHIRestoreDefaultGuestHandlerV1 *defaultHandlerV1;
-};
-
-
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * ghiSetOutlookTempFolder.x --
- *
- * Definition of the data structures used in the GuestRpc commands to
- * set or restore the temporary folder path used by Microsoft Outlook
- * to store attachments opened by the user.
- */
-
-#include "ghiCommonDefines.h"
-
-/*
- * Enumerates the different versions of the messages.
- */
-enum GHISetOutlookTempFolderVersion {
- GHI_SET_OUTLOOK_TEMP_FOLDER_V1 = 1
-};
-
-/*
- * The structure used for version 1 of the message.
- */
-struct GHISetOutlookTempFolderV1 {
- string targetURI<GHI_HANDLERS_ACTIONURI_MAX_PATH>;
-};
-
-/*
- * This defines the protocol for a 'setOutlookTempFolder' message.
- *
- * The union allows us to introduce new versions of the protocol later by
- * creating new values in the enumeration, without having to change much of
- * the code calling the (de)serialization functions.
- *
- * Since the union doesn't have a default case, de-serialization will fail if
- * an unknown version is provided on the wire.
- */
-union GHISetOutlookTempFolder switch (GHISetOutlookTempFolderVersion ver) {
-case GHI_SET_OUTLOOK_TEMP_FOLDER_V1:
- struct GHISetOutlookTempFolderV1 *setOutlookTempFolderV1;
-};
-
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * ghiShellAction.x --
- *
- * Definition of the data structures used in the GuestRpc commands to
- * open files, applications or URLs in either guest or host.
- */
-
-
-/*
- * Enumerates the different versions of the messages.
- */
-enum GHIShellActionVersion {
- GHI_SHELL_ACTION_V1 = 1
-};
-
-/*
- * The Windows MAX_PATH define specifies that paths may be up to 260 character
- * units in length. To allow for expansion when going to UTF8 we multiply that
- * value by 4 here.
- */
-const GHI_SHELL_ACTION_URI_MAX_SIZE = 1040;
-
-/*
- * Maximum size of a location URI - although RFC2397 doesn't define a max size
- * for a URI some browsers may limit the URI size so we define a hard limit
- * for URI's at 8K in length (this matches a limit in IE8 for example)
- */
-const GHI_SHELL_ACTION_LOCATION_MAX_SIZE = 8192;
-
-/*
- * Maximum number of locations that may be encoded in a single
- * XDR array.
- */
-const GHI_SHELL_ACTION_MAX_NUM_LOCATIONS = 32;
-
-struct GHIShellActionLocation {
- string location<GHI_SHELL_ACTION_LOCATION_MAX_SIZE>;
-};
-
-struct GHIShellActionV1 {
- /*
- * The actionURI - typically something like x-vmware-action:///run or
- * x-vmware-action:///browse.
- */
- string actionURI<GHI_SHELL_ACTION_URI_MAX_SIZE>;
-
- /*
- * The target of the action - may be a URI encoded path to an executable.
- */
- string targetURI<GHI_SHELL_ACTION_URI_MAX_SIZE>;
-
- /*
- * A list of locations to be operated on using the actionURI and targetURI.
- */
- struct GHIShellActionLocation locations<GHI_SHELL_ACTION_MAX_NUM_LOCATIONS>;
-};
-
-/*
- * This defines the protocol for a 'shellAction' messages. The union allows
- * us to create new versions of the protocol later by creating new values
- * in the GHIShellActionVersion enumeration, without having to change much of
- * the code calling the (de)serialization functions.
- *
- * Since the union doesn't have a default case, de-serialization will fail
- * if an unknown version is provided on the wire.
- */
-union GHIShellAction switch (GHIShellActionVersion ver) {
-case GHI_SHELL_ACTION_V1:
- struct GHIShellActionV1 *actionV1;
-};
-
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * ghiStartMenu.x --
- *
- * Definition of the data structures used in the GuestRpc commands to
- * indicate changes in the guest launch (aka start) menu.
- */
-
-const GHI_LAUNCH_MENU_MAX_KEY_LENGTH = 32;
-const GHI_LAUNCH_MENU_CHANGED_MAX_KEYS = 16;
-
-/*
- * Enumerates the different versions of the messages.
- */
-enum GHIStartMenuChangedVersion {
- GHI_STARTMENU_CHANGED_V1 = 1
-};
-
-
-typedef string GHILaunchMenuKey<GHI_LAUNCH_MENU_MAX_KEY_LENGTH>;
-/*
- * The structure used for version 1 of the message.
- */
-struct GHIStartMenuChangedV1 {
- /*
- * A list of the folder keys (see public/unityCommon.h) that have just changed.
- */
- GHILaunchMenuKey keys<GHI_LAUNCH_MENU_CHANGED_MAX_KEYS>;
-};
-
-
-/*
- * This defines the protocol for a 'GHIStartMenuChanged' message.
- *
- * The union allows us to introduce new versions of the protocol later by
- * creating new values in the enumeration, without having to change much of
- * the code calling the (de)serialization functions.
- *
- * Since the union doesn't have a default case, de-serialization will fail if
- * an unknown version is provided on the wire.
- */
-union GHIStartMenuChanged switch (GHIStartMenuChangedVersion ver) {
-case GHI_STARTMENU_CHANGED_V1:
- struct GHIStartMenuChangedV1 *ghiStartMenuChangedV1;
-};
-
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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.
- *
- *********************************************************/
-
-/*
- * ghiTclo.cpp --
- *
- * Guest-host integration functions.
- */
-
-#include "appUtil.h"
-#include "ghIntegration.h"
-#include "ghiTclo.h"
-
-extern "C" {
-#include "vmware.h"
-#include "vmware/tools/guestrpc.h"
-#include "debug.h"
-#include "dynxdr.h"
-#include "guest_msg_def.h"
-#include "rpcin.h"
-#include "rpcout.h"
-#include "str.h"
-#include "strutil.h"
-#include "unityCommon.h"
-#include "util.h"
-#include "xdrutil.h"
-};
-
-#include "guestrpc/ghiGetBinaryHandlers.h"
-#include "guestrpc/ghiGetExecInfoHash.h"
-#include "guestrpc/ghiProtocolHandler.h"
-#include "guestrpc/ghiSetFocusedWindow.h"
-#include "guestrpc/ghiSetGuestHandler.h"
-#include "guestrpc/ghiSetOutlookTempFolder.h"
-#include "guestrpc/ghiShellAction.h"
-#include "guestrpc/ghiStartMenu.h"
-#include "guestrpc/ghiTrayIcon.h"
-#include "vmware/guestrpc/capabilities.h"
-
-static DynBuf gTcloUpdate;
-
-/*
- * Overhead of encoding the icon data in a dynbuf - used to make sure we don't
- * exceed GUEST_MSG_MAX_IN_SIZE when serializing the icons for an app.
- */
-static const int GHI_ICON_OVERHEAD = 1024;
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHITcloInit --
- *
- * Initialize the global state (a Dynbuf) used to handle the TCLO parsing
- * and dispatch.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-GHITcloInit()
-{
- DynBuf_Init(&gTcloUpdate);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHITcloCleanup --
- *
- * Cleanup the global state (a Dynbuf) used to handle the TCLO parsing
- * and dispatch.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-GHITcloCleanup()
-{
- DynBuf_Destroy(&gTcloUpdate);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHITcloGetBinaryInfo --
- *
- * RPC handler for 'unity.get.binary.info'. Get required binary info
- * and send it back to the VMX.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloGetBinaryInfo(RpcInData *data) // IN/OUT
-{
- char *binaryPathUtf8;
- DynBuf *buf = &gTcloUpdate;
- DynBuf iconDataBuf;
- unsigned int index = 0;
- Bool ret = TRUE;
- std::string friendlyName;
- std::list<GHIBinaryIconInfo> iconList;
- char temp[128]; // Used to hold sizes and indices as strings
- uint32 serializedIconCount = 0;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- /* Skip the leading space. */
- index++;
-
- /* The binary path provided by the VMX is in UTF8. */
- binaryPathUtf8 = StrUtil_GetNextToken(&index, data->args, "");
-
- if (!binaryPathUtf8) {
- Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data,
- "Invalid arguments. Expected \"binary_path\"",
- FALSE);
- goto exit;
- }
-
- DynBuf_SetSize(buf, 0);
-
- if (!GHI_GetBinaryInfo(binaryPathUtf8, friendlyName, iconList)) {
- Debug("%s: Could not get binary info.\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data,
- "Could not get binary info",
- FALSE);
- goto exit;
- }
-
- /*
- * Append the name to the output buffer now. If we fail to get the
- * icons, we still want to return the app name. Then the UI can display
- * the default icon and correct app name.
- *
- * The output buffer should look like this:
- * <name>\0<icon count>\0<width>\0<height>\0<size>\0<bgraData>\0...
- *
- * Note that the icon data is in BGRA format. An alpha channel value of 255 means
- * "fully opaque", and an alpha channel value of 0 means "fully transparent".
- */
-
- DynBuf_AppendString(buf, friendlyName.c_str());
-
- if (iconList.size() <= 0) {
- Debug("%s: Could not find any icons for path: %s", __FUNCTION__, binaryPathUtf8);
- }
-
- DynBuf_Init(&iconDataBuf);
- /* Copy icon info to the output buffer. */
- for (std::list<GHIBinaryIconInfo>::const_iterator it = iconList.begin();
- it != iconList.end();
- it++) {
- /*
- * XXX: The backdoor has a maximum RPC data size of 64K - don't attempt to send
- * icons larger than this size.
- */
- if ((DynBuf_GetSize(&iconDataBuf) + it->dataBGRA.size()) <
- GUESTMSG_MAX_IN_SIZE - GHI_ICON_OVERHEAD) {
- Str_Sprintf(temp, sizeof temp, "%u", it->width);
- DynBuf_AppendString(&iconDataBuf, temp);
-
- Str_Sprintf(temp, sizeof temp, "%u", it->height);
- DynBuf_AppendString(&iconDataBuf, temp);
-
- Str_Sprintf(temp, sizeof temp, "%u", (int32) it->dataBGRA.size());
- DynBuf_AppendString(&iconDataBuf, temp);
-
- DynBuf_Append(&iconDataBuf, &(it->dataBGRA[0]),
- it->dataBGRA.size());
- DynBuf_AppendString(&iconDataBuf, "");
-
- serializedIconCount++;
- }
- }
-
- Str_Sprintf(temp, sizeof temp, "%d", serializedIconCount);
- DynBuf_AppendString(buf, temp);
-
- /* Append the icon data */
- DynBuf_Append(buf, DynBuf_Get(&iconDataBuf), DynBuf_GetSize(&iconDataBuf));
- DynBuf_Destroy(&iconDataBuf);
-
- /*
- * Write the final result into the result out parameters and return!
- */
- data->result = (char *)DynBuf_Get(buf);
- data->resultLen = DynBuf_GetSize(buf);
-
-exit:
- free(binaryPathUtf8);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHITcloGetBinaryHandlers --
- *
- * RPC handler for 'unity.get.binary.handlers'. Get filetypes supported
- * by the binary and send it back to the VMX.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloGetBinaryHandlers(RpcInData *data) // IN/OUT
-{
- char *binaryPathUtf8;
- XDR xdrs;
- unsigned int index = 0;
- Bool ret = TRUE;
- GHIBinaryHandlersList *handlersList = NULL;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- /* Skip the leading space. */
- index++;
-
- /* The binary path provided by the VMX is in UTF8. */
- binaryPathUtf8 = StrUtil_GetNextToken(&index, data->args, "");
-
- if (!binaryPathUtf8) {
- Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments. Expected \"binary_path\"", FALSE);
- }
-
- handlersList = (GHIBinaryHandlersList *) Util_SafeCalloc(1, sizeof *handlersList);
- ASSERT_MEM_ALLOC(DynXdr_Create(&xdrs));
-
-#if !defined(OPEN_VM_TOOLS)
- FileTypeList::const_iterator fileTypeIterator;
- FileTypeList aFileTypeList;
-
- aFileTypeList = GHI_GetBinaryHandlers(binaryPathUtf8);
-
- /*
- * Take the list of filetypes handled by this application and convert it into
- * the XDR based structure that we'll then serialize
- */
-
- int fileTypeCount;
- for (fileTypeIterator = aFileTypeList.begin(), fileTypeCount = 0;
- (fileTypeIterator != aFileTypeList.end()) &&
- (fileTypeCount < GHI_MAX_NUM_BINARY_HANDLERS);
- ++fileTypeIterator, ++fileTypeCount)
- {
- std::string extension = (*fileTypeIterator)->Extension();
- size_t extensionStringLength = strlen(extension.c_str()) + 1;
- std::string actionURI = (*fileTypeIterator)->GetActionURIList().front();
- size_t actionURILength = strlen(actionURI.c_str()) + 1;
-
- /*
- * Copy the handlers suffix/extension string.
- */
- GHIBinaryHandlersDetails *aHandler = (GHIBinaryHandlersDetails *)
- XDRUTIL_ARRAYAPPEND(handlersList,
- handlers,
- 1);
- ASSERT_MEM_ALLOC(aHandler);
- aHandler->suffix = (char *) Util_SafeCalloc(extensionStringLength,
- sizeof *aHandler->suffix);
- Str_Strcpy(aHandler->suffix, extension.c_str(), extensionStringLength);
-
- /*
- * Empty strings for all the other 'type' fields. Note that we cannot leave the
- * string pointer as NULL, we must encode an empty string for XDR to work.
- */
- aHandler->mimetype = (char *) Util_SafeCalloc(1, sizeof *aHandler->mimetype);
- aHandler->mimetype[0] = '\0';
- aHandler->UTI = (char *) Util_SafeCalloc(1, sizeof *aHandler->UTI);
- aHandler->UTI[0] = '\0';
-
- /*
- * Set the Action URI and friendly name for this type
- */
- GHIBinaryHandlersActionURIPair *anActionPair = (GHIBinaryHandlersActionURIPair *)
- XDRUTIL_ARRAYAPPEND(aHandler,
- actionURIs,
- 1);
- ASSERT_MEM_ALLOC(anActionPair);
- anActionPair->actionURI = (char *) Util_SafeCalloc(actionURILength,
- sizeof *anActionPair->actionURI);
- Str_Strcpy(anActionPair->actionURI, actionURI.c_str(), actionURILength);
- anActionPair->verb = Util_SafeStrdup("run");
-
- std::string friendlyName = (*fileTypeIterator)->FriendlyName();
- size_t friendlyNameLength = strlen(friendlyName.c_str()) + 1;
- aHandler->friendlyName = (char *) Util_SafeCalloc(friendlyNameLength,
- sizeof *aHandler->friendlyName);
- Str_Strcpy(aHandler->friendlyName, friendlyName.c_str(), friendlyNameLength);
-
- /*
- * Store the list of icon dimensions and URIs.
- * TODO: Retrieve the list of icons and their dimensions for this filetype.
- */
- }
-#endif // OPEN_VM_TOOLS
-
- GHIBinaryHandlers message;
- message.ver = GHI_BINARY_HANDLERS_V1;
- message.GHIBinaryHandlers_u.handlersV1 = handlersList;
-
- ret = xdr_GHIBinaryHandlers(&xdrs, &message);
- if (ret == FALSE) {
- Debug("%s: Failed to serialize binary handlers list.\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data, "Failed to serialize binary handlers list.", FALSE);
- goto exitWithXDRCleanup;
- }
-
- /*
- * If the serialized data exceeds our maximum message size we have little choice
- * but to fail the request and log the oversize message.
- */
- if (xdr_getpos(&xdrs) > GUESTMSG_MAX_IN_SIZE) {
- ret = RPCIN_SETRETVALS(data, "Filetype list too large", FALSE);
- goto exitWithXDRCleanup;
- }
-
- /*
- * Write the final result into the result out parameters and return!
- */
- data->result = reinterpret_cast<char *>(DynXdr_Get(&xdrs));
- data->resultLen = xdr_getpos(&xdrs);
- data->freeResult = TRUE;
- ret = TRUE;
-
-exitWithXDRCleanup:
- VMX_XDR_FREE(xdr_GHIBinaryHandlers, &message);
- /*
- * Destroy the XDR structure but leave the data buffer alone since it will be
- * freed by the RpcIn layer.
- */
- DynXdr_Destroy(&xdrs, FALSE);
- free(binaryPathUtf8);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHITcloOpenStartMenu --
- *
- * RPC handler for 'unity.launchmenu.open'. Get the start menu sub-tree
- * for a given item, save it in the array so it can be accessed
- * later when the VMX needs to iterate over the items. Return the count
- * of the items in the sub-tree and a handle to this sub-tree. The handle
- * will be used by the VMX to iterate over the sub-items.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloOpenStartMenu(RpcInData *data) // IN/OUT
-{
- char *rootUtf8 = NULL;
- DynBuf *buf = &gTcloUpdate;
- uint32 flags = 0;
- uint32 index = 0;
- uint32 menuHandle = 0;
- uint32 numItems = 0;
-
- Bool ret = TRUE;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- /* Skip the leading space. */
- index++;
-
- /* The start menu root provided by the VMX is in UTF8. */
- rootUtf8 = StrUtil_GetNextToken(&index, data->args, "");
-
- if (!rootUtf8) {
- Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data,
- "Invalid arguments. Expected \"root\"",
- FALSE);
- goto exit;
- }
-
- /*
- * Skip the NULL after the root, and look for the flags. Old versions of
- * the VMX don't send this parameter, so it's not an error if it is not
- * present in the RPC.
- */
- if (++index < data->argsSize && sscanf(data->args + index, "%u", &flags) != 1) {
- Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data,
- "Invalid arguments. Expected flags",
- FALSE);
- goto exit;
- }
-
- DynBuf_SetSize(buf, 0);
-#if !defined(OPEN_VM_TOOLS)
- if (!GHI_OpenStartMenuTree(rootUtf8, flags, menuHandle, numItems)) {
- Debug("%s: Could not open start menu.\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data,
- "Could not get start menu count",
- FALSE);
- goto exit;
- } else {
- char temp[256];
- Str_Sprintf(temp, sizeof temp, "%d %d", menuHandle, numItems);
- DynBuf_AppendString(buf, temp);
- }
-#endif // OPEN_VM_TOOLS
-
- /*
- * Write the final result into the result out parameters and return!
- */
- data->result = (char *)DynBuf_Get(buf);
- data->resultLen = DynBuf_GetSize(buf);
-
-exit:
- free(rootUtf8);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHITcloGetStartMenuItem --
- *
- * RPC handler for 'unity.launchmenu.next'. Get the start menu item
- * at the given index for the tree with a given handle.
- * If there's no item at the given index, return FALSE.
- *
- * Results:
- * TRUE if the item was found.
- * FALSE otherwise (i.e. if the VMX provides a wrong handle or if there's
- no items left).
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloGetStartMenuItem(RpcInData *data) // IN/OUT
-{
- DynBuf *buf = &gTcloUpdate;
- uint32 index = 0;
- Bool ret = TRUE;
- uint32 itemIndex = 0;
- uint32 handle = 0;
-#if !defined(OPEN_VM_TOOLS)
- Bool isSubmenu;
- utf::string menuPath;
- utf::string itemPathURI;
- utf::string itemName;
-#endif // OPEN_VM_TOOLS
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- /* Parse the handle of the menu tree that VMX wants. */
- if (!StrUtil_GetNextUintToken(&handle, &index, data->args, " ")) {
- Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data,
- "Invalid arguments. Expected handle index",
- FALSE);
- }
-
- /* The index of the menu item to be send back. */
- if (!StrUtil_GetNextUintToken(&itemIndex, &index, data->args, " ")) {
- Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data,
- "Invalid arguments. Expected handle index",
- FALSE);
- }
-
- DynBuf_SetSize(buf, 0);
-#if !defined(OPEN_VM_TOOLS)
- if (!GHI_GetStartMenuItem(handle, itemIndex,
- isSubmenu, menuPath, itemPathURI, itemName)) {
- Debug("%s: Could not get start menu item.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data,
- "Could not get start menu item",
- FALSE);
- }
-
- DynBuf_AppendString(buf, menuPath.c_str());
- DynBuf_AppendString(buf, isSubmenu ? "1" : "0");
- DynBuf_AppendString(buf, itemPathURI.c_str());
- DynBuf_AppendString(buf, itemName.c_str());
-#else
- return RPCIN_SETRETVALS(data,
- "Could not get start menu item",
- FALSE);
-#endif // OPEN_VM_TOOLS
-
- /*
- * Write the final result into the result out parameters and return!
- */
- data->result = (char *)DynBuf_Get(buf);
- data->resultLen = DynBuf_GetSize(buf);
-
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHITcloCloseStartMenu --
- *
- * RPC handler for 'unity.launchmenu.close'. The VMX is done with this
- * particular start menu tree. Free all memory and cleanup.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Memory allocated when the start menu tree was opened is finally freed.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloCloseStartMenu(RpcInData *data) // IN/OUT
-{
- uint32 index = 0;
- int32 handle = 0;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- /* Parse the handle of the menu tree that VMX wants. */
- if (!StrUtil_GetNextIntToken(&handle, &index, data->args, " ")) {
- Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data,
- "Invalid arguments. Expected handle",
- FALSE);
- }
-
-#if !defined(OPEN_VM_TOOLS)
- GHI_CloseStartMenuTree(handle);
-#endif // OPEN_VM_TOOLS
-
- return RPCIN_SETRETVALS(data, "", TRUE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHITcloShellOpen --
- *
- * RPC handler for 'unity.shell.open'. Open the specified file with the
- * default shell handler. Note that the file path may be either a URI
- * (originated with Tools >= NNNNN), or a regular path (originated with
- * Tools < NNNNN).
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloShellOpen(RpcInData *data) // IN/OUT
-{
- char *fileUtf8 = NULL;
- Bool ret = TRUE;
- unsigned int index = 0;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: name: '%s', args: '%s'\n", __FUNCTION__, data->name, data->args);
-
- /* Skip the leading space. */
- index++;
-
- /* The file path provided by the VMX is in UTF8. */
- fileUtf8 = StrUtil_GetNextToken(&index, data->args, "");
-
- if (!fileUtf8) {
- Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data,
- "Invalid arguments. Expected file_name",
- FALSE);
- }
-
- ret = GHI_ShellOpen(fileUtf8);
- free(fileUtf8);
-
- if (!ret) {
- Debug("%s: Could not perform the requested shell open action.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data,
- "Could not perform the requested shell open action.",
- FALSE);
- }
-
- return RPCIN_SETRETVALS(data, "", TRUE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHITcloShellAction --
- *
- * RPC handler for "ghi.guest.shell.action". The action command has three
- * arguments: an action URI, a target URI, and an array of location URIs.
- * Action URIs are in the form: "x-vmware-action://<verb>", where <verb> is
- * the name of a specific action to perform.
- * The target URI is a guest-specific URI that was previously given to the
- * host (usually a path to an application to run). Note that this may be
- * either a URI (new Tools) or a regular path (old Tools).
- * The locations can be files or URLs. Files are typically specified as
- * HGFS shared folder locations (see below), but can potentially use the
- * "file://<path>" URIs as well.
- * Each guest can specify the features it supports using capability flags:
- *
- * Capability Description
- *
- * GHI_CAP_CMD_SHELL_ACTION Guest allows 'ghi.guest.shell.action'.
- * This encompasses this entire command
- * and the rest of the capabilities.
- *
- * GHI_CAP_SHELL_ACTION_BROWSE Guest supports the 'browse' action verb,
- * used to open a file browser window with
- * a given set of locations.
- *
- * GHI_CAP_SHELL_ACTION_RUN Guest supports the 'run' action verb,
- * used for running applications as well
- * as opening file or URL locations.
- *
- * GHI_CAP_SHELL_LOCATION_HGFS Guest supports HGFS share location URIs:
- * "x-vmware-share://<path>", where <path>
- * specifies a shared folder name and an
- * optional path within the shared folder.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloShellAction(RpcInData *data) // IN/OUT
-{
- Bool ret = TRUE;
- GHIShellAction shellActionMsg;
- GHIShellActionV1 *shellActionV1Ptr;
- memset(&shellActionMsg, 0, sizeof shellActionMsg);
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- /*
- * Build an XDR Stream from the argument data which begins are args + 1
- * since there is a space separator between the RPC name and the XDR serialization.
- */
- if (!XdrUtil_Deserialize((char *)data->args + 1, data->argsSize - 1,
- (void *)xdr_GHIShellAction, &shellActionMsg)) {
- Debug("%s: Failed to deserialize data\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data,
- "Failed to deserialize data.",
- FALSE);
- goto exit;
- }
-
- ASSERT(shellActionMsg.ver == GHI_SHELL_ACTION_V1);
- if (shellActionMsg.ver != GHI_SHELL_ACTION_V1) {
- Debug("%s: Unexpected XDR version = %d\n", __FUNCTION__, shellActionMsg.ver);
- ret = RPCIN_SETRETVALS(data,
- "Unexpected XDR version.",
- FALSE);
- goto exit;
- }
-
- shellActionV1Ptr = shellActionMsg.GHIShellAction_u.actionV1;
- ret = GHI_ShellAction(shellActionV1Ptr->actionURI,
- shellActionV1Ptr->targetURI,
- (const char **)shellActionV1Ptr->locations.locations_val,
- shellActionV1Ptr->locations.locations_len);
- if (!ret) {
- Debug("%s: Could not perform the requested shell action.\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data,
- "Could not perform the requested shell action.",
- FALSE);
- goto exit;
- }
-
- ret = RPCIN_SETRETVALS(data, "", TRUE);
-
-exit:
- VMX_XDR_FREE(xdr_GHIShellAction, &shellActionMsg);
-
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHITcloSetGuestHandler --
- *
- * RPC handler for 'ghi.guest.handler.set'. Changes the nominated handlerType
- * to use the VMwareHostOpen proxy app to open files or URLs in the host.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloSetGuestHandler(RpcInData *data) // IN/OUT
-{
- Bool ret = FALSE;
- XDR xdrs;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s name:%s args length: %"FMTSZ"u\n", __FUNCTION__, data->name, data->argsSize);
-
- /*
- * Build an XDR Stream from the argument data which beings are args + 1
- * since there is a space separator between the RPC name and the XDR serialization.
- */
- xdrmem_create(&xdrs, (char *) data->args + 1, data->argsSize - 1, XDR_DECODE);
-
- GHISetGuestHandler setGuestHandlerMsg;
- GHISetGuestHandlerV1 *setGuestHandlerV1Ptr;
- GHISetGuestHandlerAction *aHandlerAction;
-
- memset(&setGuestHandlerMsg, 0, sizeof setGuestHandlerMsg);
- if (!xdr_GHISetGuestHandler(&xdrs, &setGuestHandlerMsg)) {
- Debug("%s: Unable to deserialize data\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data, "Unable to deserialize data.", FALSE);
- goto exitWithXDRCleanup;
- }
-
- ASSERT(setGuestHandlerMsg.ver == GHI_SET_GUEST_HANDLER_V1);
- setGuestHandlerV1Ptr = setGuestHandlerMsg.GHISetGuestHandler_u.guestHandlerV1;
- aHandlerAction = setGuestHandlerV1Ptr->actionURIs.actionURIs_val;
-
- ret = GHI_SetGuestHandler(setGuestHandlerV1Ptr->suffix,
- setGuestHandlerV1Ptr->mimetype,
- setGuestHandlerV1Ptr->UTI,
- aHandlerAction->actionURI,
- aHandlerAction->targetURI);
-
- if (ret == FALSE) {
- Debug("%s: Unable to set guest handler\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data, "Unable to set guest handler", FALSE);
- goto exitWithXDRCleanup;
- }
- /*
- * Write the final result into the result out parameters and return!
- */
- data->result = "";
- data->resultLen = 0;
- data->freeResult = FALSE;
- ret = TRUE;
-
-exitWithXDRCleanup:
- VMX_XDR_FREE(xdr_GHISetGuestHandler, &setGuestHandlerMsg);
- xdr_destroy(&xdrs);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHITcloRestoreDefaultGuestHandler --
- *
- * RPC handler for 'ghi.guest.handler.restoreDefault'. Changes the nominated
- * handlerType back to the value in use prior to any changes by tools.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloRestoreDefaultGuestHandler(RpcInData *data) // IN/OUT
-{
- Bool ret = FALSE;
- XDR xdrs;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s name:%s args length: %"FMTSZ"u\n", __FUNCTION__, data->name, data->argsSize);
-
- /*
- * Build an XDR Stream from the argument data which beings are args + 1
- * since there is a space separator between the RPC name and the XDR serialization.
- */
- xdrmem_create(&xdrs, (char *) data->args + 1, data->argsSize - 1, XDR_DECODE);
-
- GHIRestoreDefaultGuestHandler restoreMsg;
- GHIRestoreDefaultGuestHandlerV1 *restoreV1Ptr = NULL;
-
- memset(&restoreMsg, 0, sizeof restoreMsg);
- if (!xdr_GHIRestoreDefaultGuestHandler(&xdrs, &restoreMsg)) {
- Debug("%s: Unable to deserialize data\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data, "Unable to deserialize data", FALSE);
- goto exit;
- }
-
- ASSERT(restoreMsg.ver == GHI_SET_GUEST_HANDLER_V1);
- restoreV1Ptr = restoreMsg.GHIRestoreDefaultGuestHandler_u.defaultHandlerV1;
-
- ret = GHI_RestoreDefaultGuestHandler(restoreV1Ptr->suffix,
- restoreV1Ptr->mimetype,
- restoreV1Ptr->UTI);
- if (ret == FALSE) {
- Debug("%s: Unable to restore guest handler\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data, "Unable to restore guest handler", FALSE);
- goto exit;
- }
- /*
- * Write the final result into the result out parameters and return!
- */
- data->result = "";
- data->resultLen = 0;
- data->freeResult = FALSE;
- ret = TRUE;
-
-exit:
- xdr_destroy(&xdrs);
- VMX_XDR_FREE(xdr_GHIRestoreDefaultGuestHandler, &restoreMsg);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHILaunchMenuChangeRPC --
- *
- * Informs host that one or more Launch Menu changes have been detected.
- *
- * Results:
- * TRUE on success
- * FALSE on error
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-GHILaunchMenuChangeRPC(int numFolderKeys, // IN
- const char **folderKeysChanged) // IN
-{
- /* +1 for the space separator */
- char request[sizeof GHI_RPC_LAUNCHMENU_CHANGE + 1];
- XDR xdrs;
- GHIStartMenuChanged startMenuChanged;
- GHIStartMenuChangedV1 smcv1;
- Bool status;
-
- /*
- * Note: The primary contents of the startMenuChanged - the folder keys,
- * are allocated and tracked outside of this function, there's no need to call
- * VMX_XDR_FREE here for the XDR contents, in fact if called it will delete memory
- * from other parts of the system.
- */
-
- memset(&startMenuChanged, 0, sizeof startMenuChanged);
- memset(&smcv1, 0, sizeof smcv1);
-
- ASSERT_MEM_ALLOC(DynXdr_Create(&xdrs));
-
- smcv1.keys.keys_len = numFolderKeys;
- smcv1.keys.keys_val = (char **) folderKeysChanged;
-
- startMenuChanged.ver = GHI_STARTMENU_CHANGED_V1;
- startMenuChanged.GHIStartMenuChanged_u.ghiStartMenuChangedV1 = &smcv1;
-
- Str_Sprintf(request,
- sizeof request,
- "%s ",
- GHI_RPC_LAUNCHMENU_CHANGE);
-
- /* Write preamble and serialized changed folder keys to XDR stream. */
- if (!DynXdr_AppendRaw(&xdrs, request, strlen(request)) ||
- !xdr_GHIStartMenuChanged(&xdrs, &startMenuChanged)) {
- Debug("%s: could not serialize protocol handler info\n", __FUNCTION__);
- DynXdr_Destroy(&xdrs, TRUE);
- return FALSE;
- }
-
- status = RpcOut_SendOneRaw(DynXdr_Get(&xdrs),
- xdr_getpos(&xdrs),
- NULL,
- NULL);
- DynXdr_Destroy(&xdrs, TRUE);
-
- if (!status) {
- Debug("%s: could not send unity launchmenu change\n", __FUNCTION__);
- }
- return status;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHITcloSetOutlookTempFolder --
- *
- * Handler for the 'ghi.guest.outlook.set.tempFolder' RPC.
- *
- * Results:
- * If the RPC fails, return FALSE. Otherwise, returns TRUE.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloSetOutlookTempFolder(RpcInData *data) // IN/OUT: RPC data
-{
- Bool ret = FALSE;
- XDR xdrs;
-
- Debug("%s: Enter.\n", __FUNCTION__);
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: Got RPC, name: \"%s\", argument length: %"FMTSZ"u.\n",
- __FUNCTION__, data->name, data->argsSize);
-
- /*
- * Build an XDR stream from the argument data.
- *
- * Note that the argument data begins with args + 1 since there is a space
- * between the RPC name and the XDR serialization.
- */
- xdrmem_create(&xdrs, (char*) data->args + 1, data->argsSize - 1, XDR_DECODE);
-
- /* Deserialize the XDR into a GHISetOutlookTempFolder struct. */
- GHISetOutlookTempFolder folderMsg;
- GHISetOutlookTempFolderV1 *folderV1Ptr = NULL;
-
- memset(&folderMsg, 0, sizeof folderMsg);
- if (!xdr_GHISetOutlookTempFolder(&xdrs, &folderMsg)) {
- Debug("%s: Unable to deserialize data\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data, "Unable to deserialize data", FALSE);
- goto exit;
- }
-
- /*
- * Get the structure for v1 of the GHISetOutlookTempFolder XDR from the union
- * in the GHISetOutlookTempFolder struct.
- */
- ASSERT(folderMsg.ver == GHI_SET_OUTLOOK_TEMP_FOLDER_V1);
- folderV1Ptr = folderMsg.GHISetOutlookTempFolder_u.setOutlookTempFolderV1;
-
- // Call the platform implementation of our RPC.
- ret = GHI_SetOutlookTempFolder(folderV1Ptr->targetURI);
- if (ret == FALSE) {
- Debug("%s: Failed to set Outlook temporary folder.\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data, "Failed to set Outlook temporary folder", FALSE);
- goto exit;
- }
-
- /*
- * We don't have any out parameters, so we write empty values into the
- * result fields of the RpcInData structure.
- */
- RPCIN_SETRETVALS(data, "", FALSE);
-
- // Set our return value and return to the caller.
- ret = TRUE;
-
-exit:
- // Destroy the XDR stream.
- xdr_destroy(&xdrs);
- VMX_XDR_FREE(xdr_GHISetOutlookTempFolder, &folderMsg);
- Debug("%s: Exit.\n", __FUNCTION__);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GHITcloRestoreOutlookTempFolder --
- *
- * Handler for the 'ghi.guest.outlook.restore.tempFolder' RPC.
- *
- * Results:
- * If the RPC fails, return FALSE. Otherwise, returns TRUE.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloRestoreOutlookTempFolder(RpcInData *data) // IN/OUT: RPC data
-{
- Bool ret = FALSE;
-
- Debug("%s: Enter.\n", __FUNCTION__);
-
- /*
- * XXX: This RPC is no longer used/required - the RPC handler is left here
- * for compatibility with older hosts.
- */
-
- /*
- * We don't have any out parameters, so we write empty values into the
- * result fields of the RpcInData structure.
- */
- RPCIN_SETRETVALS(data, "", FALSE);
-
- // Set our return value and return to the caller.
- ret = TRUE;
-
- Debug("%s: Exit.\n", __FUNCTION__);
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GHITcloTrayIconSendEvent --
- *
- * Send a mouse or keyboard event to a tray icon.
- *
- * Results:
- * TRUE on success, FALSE on failure.
- *
- * Side effects:
- * XXX.
- *
- *-----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloTrayIconSendEvent(RpcInData *data) // IN/OUT: XXX
-{
- Bool ret = FALSE;
- GHITrayIconEventV1 *v1ptr = NULL;
- GHITrayIconEvent eventMsg;
-
- memset(&eventMsg, 0, sizeof eventMsg);
- Debug("%s: Enter.\n", __FUNCTION__);
-
- /* Check our arguments. */
- ASSERT(data);
- ASSERT(data->name);
- ASSERT(data->argsSize > 0);
-
- if (!(data && data->name && data->argsSize > 0)) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return FALSE;
- }
-
- Debug("%s: Got RPC, name: \"%s\", argument length: %"FMTSZ"u.\n",
- __FUNCTION__, data->name, data->argsSize);
-
- /*
- * Deserialize the XDR data. Note that the data begins with args + 1 since
- * there is a space between the RPC name and the XDR serialization.
- */
- if (!XdrUtil_Deserialize((char *)data->args + 1, data->argsSize - 1,
- (void *)xdr_GHITrayIconEvent, &eventMsg)) {
- Debug("%s: Failed to deserialize data\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data, "Failed to deserialize data.", FALSE);
- goto exit;
- }
- ASSERT(eventMsg.ver == GHI_TRAY_ICON_EVENT_V1);
- v1ptr = eventMsg.GHITrayIconEvent_u.trayIconEventV1;
-
- /* Call the platform implementation of our RPC. */
- ret = GHI_TrayIconSendEvent(v1ptr->iconID,
- v1ptr->event,
- v1ptr->x,
- v1ptr->y);
-
- if (ret == FALSE) {
- Debug("%s: RPC failed.\n", __FUNCTION__);
- RPCIN_SETRETVALS(data, "RPC failed", FALSE);
- } else {
- /*
- * We don't have any out parameters, so we write empty values into the
- * result fields of the RpcInData structure.
- */
- RPCIN_SETRETVALS(data, "", TRUE);
-
- /* Set our return value and return to the caller. */
- ret = TRUE;
- }
-
-exit:
- VMX_XDR_FREE(xdr_GHITrayIconEvent, &eventMsg);
- Debug("%s: Exit.\n", __FUNCTION__);
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GHITclOTrayIconStartUpdates --
- *
- * Start sending tray icon updates to the VMX.
- *
- * Results:
- * TRUE on success, FALSE on failure.
- *
- * Side effects:
- * XXX.
- *
- *-----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloTrayIconStartUpdates(RpcInData *data) // IN/OUT: XXX
-{
- Bool ret = FALSE;
-
- Debug("%s: Enter.\n", __FUNCTION__);
-
- /* Check our arguments. */
- ASSERT(data);
- ASSERT(data->name);
-
- if (!(data && data->name)) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- goto exit;
- }
-
- Debug("%s: Got RPC, name: \"%s\", argument length: %"FMTSZ"u.\n",
- __FUNCTION__, data->name, data->argsSize);
-
- if (!GHI_TrayIconStartUpdates()) {
- Debug("%s: Failed to start tray icon updates.\n", __FUNCTION__);
- RPCIN_SETRETVALS(data, "Failed to start tray icon updates", FALSE);
- goto exit;
- }
-
- /*
- * Write the result into the RPC out parameters.
- */
- ret = RPCIN_SETRETVALS(data, "", TRUE);
-
-exit:
- Debug("%s: Exit.\n", __FUNCTION__);
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GHITcloTrayIconStopUpdates --
- *
- * Stop sending tray icon updates to the VMX.
- *
- * Results:
- * TRUE on success, FALSE on failure.
- *
- * Side effects:
- * XXX.
- *
- *-----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloTrayIconStopUpdates(RpcInData *data) // IN/OUT:
-{
- Bool ret = FALSE;
-
- Debug("%s: Enter.\n", __FUNCTION__);
-
- /* Check our arguments. */
- ASSERT(data);
- ASSERT(data->name);
-
- if (!(data && data->name)) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- goto exit;
- }
-
- Debug("%s: Got RPC, name: \"%s\", argument length: %"FMTSZ"u.\n",
- __FUNCTION__, data->name, data->argsSize);
-
- if (!GHI_TrayIconStopUpdates()) {
- Debug("%s: Failed to start tray icon updates.\n", __FUNCTION__);
- RPCIN_SETRETVALS(data, "Failed to start tray icon updates", FALSE);
- goto exit;
- }
-
- /*
- * Write the result into the RPC out parameters.
- */
- ret = RPCIN_SETRETVALS(data, "", TRUE);
-
-exit:
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GHISendTrayIconUpdateRPC --
- *
- * Send the ghi.guest.trayIcon.update RPC to the host.
- *
- * Results:
- * TRUE if sent, FALSE otherwise.
- *
- * Side effects:
- * XXX.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-GHISendTrayIconUpdateRpc(XDR *xdrs) // XXX
-{
- Bool ret = FALSE;
- DynBuf outBuf;
-
- Debug("%s: Enter.\n", __FUNCTION__);
-
- /* Check our arguments. */
- ASSERT(xdrs);
- if (NULL == xdrs) {
- Debug("%s: Invalid parameter.\n", __FUNCTION__);
- goto exit;
- }
-
- /* Append our RPC name and a space to the DynBuf. */
- DynBuf_Init(&outBuf);
- if (!DynBuf_Append(&outBuf,
- GHI_RPC_TRAY_ICON_UPDATE,
- strlen(GHI_RPC_TRAY_ICON_UPDATE))) {
- Debug("%s: Failed to append RPC name to DynBuf.\n", __FUNCTION__);
- goto exit;
- }
-
- if (!DynBuf_Append(&outBuf, " ", 1)) {
- Debug("%s: Failed to append space to DynBuf.\n", __FUNCTION__);
- goto exit;
- }
-
- /* Append the XDR serialized data to the DynBuf. */
- if (!DynBuf_Append(&outBuf, DynXdr_Get(xdrs), xdr_getpos(xdrs)) )
- {
- Debug("%s: Failed to append XDR serialized data to DynBuf.\n",
- __FUNCTION__);
- goto exit;
- }
-
- if (!RpcOut_SendOneRaw(DynBuf_Get(&outBuf),
- DynBuf_GetSize(&outBuf),
- NULL,
- NULL)) {
- Debug("%s: Failed to send RPC to host!\n", __FUNCTION__);
- goto exit;
- }
-
- ret = TRUE;
-
-exit:
- DynBuf_Destroy(&outBuf);
- Debug("%s: Exit.\n", __FUNCTION__);
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GHITcloSetFocusedWindow --
- *
- * Set the specified window to be focused (NULL or zero window ID indicates
- * that no window should be focused).
- *
- * Results:
- * TRUE on success, FALSE otherwise.
- *
- * Side effects:
- * XXX.
- *
- *-----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloSetFocusedWindow(RpcInData *data)
-{
- Bool ret = FALSE;
- XDR xdrs;
-
- Debug("%s: Enter.\n", __FUNCTION__);
-
- /* Check our arguments. */
- ASSERT(data);
- ASSERT(data->name);
-
- if (!(data && data->name)) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- goto exit;
- }
-
- Debug("%s: Got RPC, name: \"%s\", argument length: %"FMTSZ"u.\n",
- __FUNCTION__, data->name, data->argsSize);
-
- /*
- * Build an XDR stream from the argument data.
- *
- * Note that the argument data begins with args + 1 since there is a space
- * between the RPC name and the XDR serialization.
- */
- xdrmem_create(&xdrs, (char*) data->args + 1, data->argsSize - 1, XDR_DECODE);
-
- GHISetFocusedWindow setFocusedWindowMsg;
- GHISetFocusedWindowV1 *setFocusedWindowV1Ptr;
-
- memset(&setFocusedWindowMsg, 0, sizeof setFocusedWindowMsg);
- if (!xdr_GHISetFocusedWindow((XDR *)&xdrs, &setFocusedWindowMsg)) {
- goto exitWithXDRCleanup;
- }
-
- ASSERT(setFocusedWindowMsg.ver == GHI_SET_FOCUSED_WINDOW_V1);
- if (setFocusedWindowMsg.ver != GHI_SET_FOCUSED_WINDOW_V1) {
- Debug("%s: Unexpected XDR version = %d\n", __FUNCTION__, setFocusedWindowMsg.ver);
- ret = RPCIN_SETRETVALS(data,
- "Unexpected XDR version.",
- FALSE);
- goto exitWithXDRCleanup;
- }
-
- setFocusedWindowV1Ptr = setFocusedWindowMsg.GHISetFocusedWindow_u.setFocusedWindowV1;
-
- /* Call the platform implementation of our RPC. */
- ret = GHI_SetFocusedWindow(setFocusedWindowV1Ptr->windowId);
-
- /*
- * Write the result into the RPC out parameters.
- */
- ret = RPCIN_SETRETVALS(data, "", TRUE);
-
-exitWithXDRCleanup:
- /* Destroy the XDR stream. */
- xdr_destroy(&xdrs);
- VMX_XDR_FREE(xdr_GHISetFocusedWindow, &setFocusedWindowMsg);
-exit:
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GHITcloGetExecInfoHash --
- *
- * Get the hash (or timestamp) of information returned by
- * GHITcloGetBinaryInfo.
- *
- * Results:
- * TRUE on success, FALSE on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-gboolean
-GHITcloGetExecInfoHash(RpcInData *data) // IN/OUT:
-{
- Bool ret = TRUE;
- GHIGetExecInfoHashRequest requestMsg;
- GHIGetExecInfoHashReply replyMsg;
- XDR xdrs;
- GHIGetExecInfoHashRequestV1 *requestV1;
- GHIGetExecInfoHashReplyV1 replyV1;
- char *execHash = NULL;
-
- memset(&requestMsg, 0, sizeof requestMsg);
- memset(&replyMsg, 0, sizeof replyMsg);
-
- /* Check our arguments. */
- ASSERT(data);
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!(data && data->name && data->args)) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- goto error;
- }
-
- Debug("%s: Got RPC, name: \"%s\", argument length: %"FMTSZ"u.\n",
- __FUNCTION__, data->name, data->argsSize);
-
- /*
- * Deserialize the XDR data. Note that the data begins with args + 1 since
- * there is a space between the RPC name and the XDR serialization.
- */
- if (!XdrUtil_Deserialize((char *)data->args + 1, data->argsSize - 1,
- (void *)xdr_GHIGetExecInfoHashRequest, &requestMsg)) {
- Debug("%s: Failed to deserialize data\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data, "Failed to deserialize data.", FALSE);
- goto error;
- }
-
- ASSERT(requestMsg.ver == GHI_GET_EXEC_INFO_HASH_V1);
- if (requestMsg.ver != GHI_GET_EXEC_INFO_HASH_V1) {
- Debug("%s: Unexpected XDR version = %d\n", __FUNCTION__, requestMsg.ver);
- ret = RPCIN_SETRETVALS(data, "Unexpected XDR version.", FALSE);
- goto exit;
- }
-
- requestV1 = requestMsg.GHIGetExecInfoHashRequest_u.requestV1;
-
- /*
- * Call the platform implementation of the RPC handler.
- */
- if (!GHI_GetExecInfoHash(requestV1->execPath, &execHash)) {
- ret = RPCIN_SETRETVALS(data, "Could not get executable info hash.", FALSE);
- goto exit;
- }
-
- replyV1.execHash = execHash;
- replyMsg.ver = GHI_GET_EXEC_INFO_HASH_V1;
- replyMsg.GHIGetExecInfoHashReply_u.replyV1 = &replyV1;
-
- /*
- * Serialize the result data and return.
- */
- ASSERT_MEM_ALLOC(DynXdr_Create(&xdrs));
-
- if (!xdr_GHIGetExecInfoHashReply(&xdrs, &replyMsg)) {
- ret = RPCIN_SETRETVALS(data, "Failed to serialize data", FALSE);
- DynXdr_Destroy(&xdrs, TRUE);
- goto exit;
- }
-
- data->result = reinterpret_cast<char *>(DynXdr_Get(&xdrs));
- data->resultLen = xdr_getpos(&xdrs);
- data->freeResult = TRUE;
-
- /*
- * Destroy the serialized XDR structure but leave the data buffer alone
- * since it will be freed by the RpcIn layer.
- */
- DynXdr_Destroy(&xdrs, FALSE);
-
-exit:
- VMX_XDR_FREE(xdr_GHIGetExecInfoHashRequest, &requestMsg);
-error:
- /* Free the memory allocated in the platform layer for the hash */
- free(execHash);
- return ret;
-}
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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 ghiTclo.h
- *
- * Functions for handling/dispatching GHI TCLO RPCs.
- */
-
-#include "vmware/tools/plugin.h"
-
-extern "C" {
- #include "rpcin.h"
- #include "dynxdr.h"
-};
-
-extern "C" {
- void GHITcloInit();
- void GHITcloCleanup();
-
- /* RPC Entry points */
- gboolean GHITcloGetBinaryInfo(RpcInData *data);
- gboolean GHITcloGetBinaryHandlers(RpcInData *data);
- gboolean GHITcloGetStartMenuItem(RpcInData *data);
- gboolean GHITcloOpenStartMenu(RpcInData *data);
- gboolean GHITcloCloseStartMenu(RpcInData *data);
- gboolean GHITcloShellOpen(RpcInData *data);
- gboolean GHITcloShellAction(RpcInData *data);
- gboolean GHITcloSetGuestHandler(RpcInData *data);
- gboolean GHITcloRestoreDefaultGuestHandler(RpcInData *data);
- gboolean GHITcloSetOutlookTempFolder(RpcInData* data);
- gboolean GHITcloRestoreOutlookTempFolder(RpcInData* data);
- gboolean GHITcloTrayIconSendEvent(RpcInData *data);
- gboolean GHITcloTrayIconStartUpdates(RpcInData *data);
- gboolean GHITcloTrayIconStopUpdates(RpcInData *data);
- gboolean GHITcloSetFocusedWindow(RpcInData *data);
- gboolean GHITcloGetExecInfoHash(RpcInData *data);
-
- /* Callback functions to send data to the host */
- Bool GHISendTrayIconUpdateRpc(XDR *xdrs);
- Bool GHILaunchMenuChangeRPC(int numFolderKeys, const char **folderKeysChanged);
-};
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * ghiTrayIcon.x --
- *
- * Definition of the data structures used in the GuestRpc commands to
- * provide access to the guest tray icons to the host.
- */
-
-/*
- * Using the opaque type causes rpcgen to emit code that calls the htonl and
- * ntohl functions. On Windows, these functions are defined in winsock2.h, so
- * we need to #include that header in the generated code.
- */
-%#ifdef WIN32
-%#include "winsock2.h"
-%#endif /* WIN32 */
-
-enum GHITrayIconVersion {
- GHI_TRAY_ICON_V1 = 1
-};
-
-/* These are the values used in the op member below. */
-enum GHITrayIconOp {
- GHI_TRAY_ICON_OP_ADD = 1,
- GHI_TRAY_ICON_OP_MODIFY,
- GHI_TRAY_ICON_OP_DELETE
-};
-
-/* These are the flag values used in the flags bitmask below. */
-enum GHITrayIconFlags {
- GHI_TRAY_ICON_FLAG_PNGDATA = 1, /* The pngData is valid. */
- GHI_TRAY_ICON_FLAG_TOOLTIP = 2, /* The tooltip is valid. */
- GHI_TRAY_ICON_FLAG_BLACKLISTKEY = 4 /* The blacklistKey is valid. */
-};
-
-/*
- * These structures are sent from the guest to the host whenver a new tray
- * icon is added, or an existing tray icon is modified. When an icon is
- * modified, the flags member of this structure is used as a bitmask to
- * indicate the changed values.
- *
- * Note that the identifier string assigned to the icon should be treated as
- * an opaque value. The contents of this string may change without notice in
- * new versions of the guest tools. This identifier is not persistent.
- *
- * The blacklist key is used by the host to blacklist tray icons. We can't use
- * iconID for this purpose because iconID must be unique, and the blacklist
- * key is not always unique (see bug 461750).
- */
-struct GHITrayIconV1 {
- string iconID<>; /* opaque identifier for the icon */
- GHITrayIconOp op; /* action to perform */
- uint32 flags; /* bitmask of valid items */
- uint32 width; /* PNG image width */
- uint32 height; /* PNG image height */
- opaque pngData<>; /* PNG image data for the icon */
- string tooltip<>; /* tooltip string for the icon, UTF8 encoded */
- string blacklistKey<>; /* key used for icon blacklisting */
-};
-
-union GHITrayIcon switch (GHITrayIconVersion ver) {
-case GHI_TRAY_ICON_V1:
- struct GHITrayIconV1 *trayIconV1;
-};
-
-enum GHITrayIconEventVersion {
- GHI_TRAY_ICON_EVENT_V1 = 1
-};
-
-/*
- * Event messages are sent from the host to the guest when the user interacts
- * with the host representation of the tray icon (e.g. right-clicks on it).
- *
- * XXX The (x, y) co-ordinates in this structure must be relative to the guest
- * screen origin.
- */
-struct GHITrayIconEventV1 {
- string iconID<>; /* identifier of the icon */
- uint32 event; /* event identifier, see unityCommon.h */
- uint32 x; /* guest x co-ordinate of the event */
- uint32 y; /* guest y co-ordinate of the event */
-};
-
-union GHITrayIconEvent switch (GHITrayIconEventVersion ver) {
-case GHI_TRAY_ICON_EVENT_V1:
- struct GHITrayIconEventV1 *trayIconEventV1;
-};
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2011 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.
- *
- *********************************************************/
-
-/*
- * toolsPlugin.cpp --
- *
- * C++ wrapper bits around Tools Core C API.
- */
-
-#include "unityPlugin.h"
-
-extern "C" {
-#include <glib.h>
-
-#include "vmware.h"
-}
-
-
-namespace vmware {
-namespace tools {
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * vmware::tools::ToolsPlugin::GetSignalRegistrations --
- *
- * Returns a vector containing signal registration info (signal name,
- * callback, callback context). Signals will be connected by container
- * after all plugins have successfully registered.
- *
- * Results:
- * Vector of signal registration info.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-std::vector<ToolsPluginSignalCb>
-ToolsPlugin::GetSignalRegistrations(ToolsPluginData* pdata) // IN: plugin private data
- const
-{
- std::vector<ToolsPluginSignalCb> signals;
- signals.push_back(
- ToolsPlugin::SignalCtx(TOOLS_CORE_SIG_RESET, (void*)OnCReset, pdata));
- signals.push_back(
- ToolsPlugin::SignalCtx(TOOLS_CORE_SIG_SHUTDOWN, (void*)OnCShutdown, pdata));
- signals.push_back(
- ToolsPlugin::SignalCtx(TOOLS_CORE_SIG_CAPABILITIES, (void*)OnCCapabilities,
- pdata));
- signals.push_back(
- ToolsPlugin::SignalCtx(TOOLS_CORE_SIG_SET_OPTION, (void*)OnCSetOption, pdata));
- return signals;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * vmware::tools::ToolsPlugin::OnCReset --
- *
- * Handles Tools RPC reset signal. Acts as thunk between C callback and
- * Reset member function.
- *
- * Results:
- * TRUE on success, FALSE on failure.
- *
- * Side effects:
- * Varies. See child classes' Reset implementations.
- *
- *-----------------------------------------------------------------------------
- */
-
-gboolean
-ToolsPlugin::OnCReset(gpointer src, // IN: Event source.
- ToolsAppCtx* ctx, // IN: The app context.
- ToolsPluginData* plugin) // IN: Plugin registration data.
-{
- ASSERT(ctx != NULL);
- g_debug("%s: reset signal for app %s\n", __FUNCTION__, ctx->name);
-
- ToolsPlugin *pluginInstance = reinterpret_cast<ToolsPlugin*>(plugin->_private);
- ASSERT(pluginInstance);
-
- return pluginInstance->Reset(src);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * vmware::tools::ToolsPlugin::OnCShutdown --
- *
- * Handler for plugin shutdown event. Thunks to C++ Shutdown member
- * function and deletes the ToolsPlugin instance.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Nukes ToolsPlugin.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-ToolsPlugin::OnCShutdown(gpointer src, // IN: The source object.
- ToolsAppCtx *ctx, // IN: The app context.
- ToolsPluginData *plugin) // Plugin registration data.
-{
- g_debug("%s: shutdown signal.\n", __FUNCTION__);
-
- ToolsPlugin *pluginInstance = reinterpret_cast<ToolsPlugin*>(plugin->_private);
- ASSERT(pluginInstance);
-
- pluginInstance->Shutdown(src);
-
- delete pluginInstance;
- plugin->_private = NULL;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * vmware::tools::ToolsPlugin::OnCCapabilities --
- *
- * Handler for plugin capability (un)registration event.
- *
- * Results:
- * A list of capabilities to be sent to the host.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-GArray*
-ToolsPlugin::OnCCapabilities(
- gpointer src, // IGNORED
- ToolsAppCtx *ctx, // IN: The app context.
- gboolean set, // IN: true if setting, else unsetting
- ToolsPluginData *plugin) // IN: Plugin registration data.
-{
- ToolsPlugin *pluginInstance = reinterpret_cast<ToolsPlugin*>(plugin->_private);
- ASSERT(pluginInstance);
-
- std::vector<ToolsAppCapability> capabilities = pluginInstance->GetCapabilities(set);
-
- g_debug("%s: got capability signal, setting = %d.\n", __FUNCTION__, set);
- return VMTools_WrapArray(&capabilities[0], sizeof capabilities[0],
- capabilities.size());
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * vmware::tools::ToolsPlugin::OnCSetOption --
- *
- * Handler for host->guest "set option" event.
- *
- * Results:
- * TRUE on success, FALSE on failure.
- *
- * Side effects:
- * Varies. See child classes' SetOption implementations.
- *
- *-----------------------------------------------------------------------------
- */
-
-gboolean
-ToolsPlugin::OnCSetOption(gpointer src, // IN: Event source.
- ToolsAppCtx *ctx, // IN: The app context.
- const gchar *option, // IN: Option to set.
- const gchar *value, // IN: Option value.
- ToolsPluginData *plugin) // IN: Plugin registration data.
-{
- g_debug("%s: set '%s' to '%s'\n", __FUNCTION__, option, value);
- ToolsPlugin *pluginInstance = reinterpret_cast<ToolsPlugin*>(plugin->_private);
- ASSERT(pluginInstance);
-
- return pluginInstance->SetOption(src, std::string(option), std::string(value));
-}
-
-
-} // namespace tools
-} // namespace vmware
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * unity.x --
- *
- * Definition of the data structures used in the GuestRpc commands to
- * enable/disable and manipulate unity.
- *
- * XXX: We should move unityActive.x into this file to avoid a 'plethora' of XDR
- * sources for Unity.
- */
-
-/*
- * Include unityCommon for the definitions of the types of operations.
- */
-%#include "unityCommon.h"
-
-/*
- * Enumerates the different versions of the messages.
- */
-enum UnityOptionsVersion {
- UNITY_OPTIONS_V1 = 1
-};
-
-/*
- * The structure used for version 1 of the message.
- */
-struct UnityOptionsV1 {
- int featureMask;
-};
-
-/*
- * This defines the protocol for a 'unityOptions' message.
- *
- * The union allows us to introduce new versions of the protocol later by
- * creating new values in the enumeration, without having to change much of
- * the code calling the (de)serialization functions.
- *
- * Since the union doesn't have a default case, de-serialization will fail if
- * an unknown version is provided on the wire.
- */
-union UnityOptions switch (UnityOptionsVersion ver) {
-case UNITY_OPTIONS_V1:
- struct UnityOptionsV1 *unityOptionsV1;
-};
-
-
-/*
- * Unity Request, Confirm and Acknowledge XDR structures.
- *
- * The guest will request (from the host) that it be allowed to perform certain types
- * of window operations - for example minimize, the host will later confirm that the
- * guest can (or cannot) go ahead with the operation. Once the guest has performed
- * the requested operation it will acknowledge its completion back to the host.
- * In many ways this is analagous to the three way handshaking used by TCP.
- */
-
-/*
- * Enumerates the different versions of the messages. Note that all three types of
- * messages (request, confirm, acknowledge) share the same version value. They must
- * be managed together when updating versions.
- */
-enum UnityOperationVersion {
- UNITY_OP_V1 = 1
-};
-
-/*
- * The structure used to distinguish the operations of the message.
- */
-union UnityOperationDetails switch (int op) {
-case MINIMIZE:
- int dummy; /* Dummy value to avoid empty union */
-};
-
-struct UnityRequestOperationV1 {
- /*
- * sequence should be used to associate a request with a later confirmation so that
- * state can be maintained within the guest as to oustanding requests (or to set
- * an error for requests that must maintain order and do not reflect the order
- * back correctly.).
- */
- int sequence;
- int windowId;
- UnityOperationDetails details;
-};
-
-struct UnityConfirmOperationV1 {
- int sequence;
- int windowId;
- UnityOperationDetails details;
- bool allow;
-};
-
-/*
- * This defines the protocol for a 'unityRequestOperation' message.
- *
- * The union allows us to introduce new versions of the protocol later by
- * creating new values in the enumeration, without having to change much of
- * the code calling the (de)serialization functions.
- *
- * Since the union doesn't have a default case, de-serialization will fail if
- * an unknown version is provided on the wire.
- */
-union UnityRequestOperation switch (UnityOperationVersion ver) {
-case UNITY_OP_V1:
- struct UnityRequestOperationV1 *unityRequestOpV1;
-};
-
-union UnityConfirmOperation switch (UnityOperationVersion ver) {
-case UNITY_OP_V1:
- struct UnityConfirmOperationV1 *unityConfirmOpV1;
-};
-
-/*
- * Protocol to send the scraped/grabbed contents of a window to the host.
- */
-enum UnityWindowContentsVersion {
- UNITY_WINDOW_CONTENTS_V1 = 1
-};
-
-
-/*
- * Message used to begin the transfer of the scraped window contents to the
- * host.
- */
-struct UnityWindowContentsStartV1
-{
- uint32 windowID; /* The UnityWindowId of the window. */
- uint32 imageWidth; /* The width of the image. */
- uint32 imageHeight; /* The height of the image. */
- uint32 imageLength; /* The total length of the data for the image. */
-};
-
-
-/*
- * Message used to signal the end of the transfer of the scraped window contents
- * to the host.
- */
-struct UnityWindowContentsEndV1
-{
- uint32 windowID; /* The UnityWindowId of the window. */
-};
-
-
-/*
- * The maximum size of the image data in a UnityWindowContentsChunk.
- */
-const UNITY_WINDOW_CONTENTS_MAX_CHUNK_SIZE = 49152;
-
-/*
- * Message used to transfer a portion of the scraped window contents to the
- * host.
- */
-struct UnityWindowContentsChunkV1
-{
- uint32 windowID; /* The UnityWindowId of the window. */
- uint32 chunkID; /* The sequence number of this chunk. */
- opaque data<UNITY_WINDOW_CONTENTS_MAX_CHUNK_SIZE>;
-};
-
-
-union UnityWindowContentsChunk switch (UnityWindowContentsVersion ver) {
-case UNITY_WINDOW_CONTENTS_V1:
- struct UnityWindowContentsChunkV1 *chunkV1;
-};
-
-
-union UnityWindowContentsStart switch (UnityWindowContentsVersion ver) {
-case UNITY_WINDOW_CONTENTS_V1:
- struct UnityWindowContentsStartV1 *startV1;
-};
-
-
-union UnityWindowContentsEnd switch (UnityWindowContentsVersion ver) {
-case UNITY_WINDOW_CONTENTS_V1:
- struct UnityWindowContentsEndV1 *endV1;
-};
-
-
-/*
- * Protocol to request the contents for a list of Unity windows.
- */
-const UNITY_MAX_NUM_WINDOWS_PER_REQUEST = 256;
-
-struct UnityWindowContentsRequestV1 {
- uint32 windowID<UNITY_MAX_NUM_WINDOWS_PER_REQUEST>;
-};
-
-union UnityWindowContentsRequest switch (UnityWindowContentsVersion ver) {
-case UNITY_WINDOW_CONTENTS_V1:
- struct UnityWindowContentsRequestV1 *requestV1;
-};
-
-/*
- * Message used to register the presence of a PBRPC server in the guest for
- * handling Unity & GHI operations. This message is sent by the guest to
- * bootstrap the process of talking via a 'non-backdoor' channel between guest
- * and host.
- */
-
-const UNITY_REGISTER_PBRPCSERVER_ADDRESS_LEN = 256;
-
-enum UnityRegisterPbrpcServerVersion {
- UNITY_REGISTER_PBRPCSERVER_V1 = 1
-};
-
-struct UnityRegisterPbrpcServerV1 {
- uint32 addressFamily;
- string address<UNITY_REGISTER_PBRPCSERVER_ADDRESS_LEN>;
- uint32 port;
-};
-
-union UnityRegisterPbrpcServer switch (UnityRegisterPbrpcServerVersion ver) {
-case UNITY_REGISTER_PBRPCSERVER_V1:
- struct UnityRegisterPbrpcServerV1* registerV1;
-};
-
-
-/*
- * Mouse wheel.
- */
-
-enum UnityMouseWheelVersion {
- UNITY_MOUSE_WHEEL_V1 = 1
-};
-
-struct UnityMouseWheelV1
-{
- int32 deltaX;
- int32 deltaY;
- int32 deltaZ;
- uint32 modifierFlags;
-};
-
-union UnityMouseWheel switch (UnityMouseWheelVersion ver) {
-case UNITY_MOUSE_WHEEL_V1:
- struct UnityMouseWheelV1 *mouseWheelV1;
-};
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * unityActive.x --
- *
- * Definition of the data structures used in the GuestRpc commands to
- * provide information about the unity state.
- */
-
-enum UnityActiveVersion {
- UNITY_ACTIVE_V1 = 1
-};
-
-union UnityActiveProto switch (UnityActiveVersion ver) {
-case UNITY_ACTIVE_V1:
- Bool unityActive;
-};
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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.
- *
- *********************************************************/
-
-/*
- * unityPlugin.cpp --
- *
- * Implements an object that provides the entry points for tools unity
- * plugin.
- */
-
-#include "vmware/tools/plugin.h"
-
-extern "C" {
- #include "vmware.h"
- #include "conf.h"
- #include "debug.h"
- #include "dynxdr.h"
- #include "guestrpc/unity.h"
- #include "guestrpc/unityActive.h"
- #include "rpcin.h"
- #include "strutil.h"
- #if defined(OPEN_VM_TOOLS)
- #include "unitylib/unity.h"
- #else
- #include "unity.h"
- #endif // OPEN_VM_TOOLS
- #include "xdrutil.h"
-};
-
-#include "ghIntegration.h"
-#include "ghiTclo.h"
-#include "unityPlugin.h"
-#include "unityTclo.h"
-#if defined(G_PLATFORM_WIN32)
-#include "NotifyIconRpcCallback.h"
-#endif // G_PLATFORM_WIN32
-
-#define UNITY_CAP_NAME "unity"
-
-namespace vmware { namespace tools {
-
-/*
- * The static instance of the notification icon RPC callback object. This object
- * sends an RPC to the VMX in response to any change to the set of notification
- * icons.
- */
-#if defined(G_PLATFORM_WIN32)
-static NotifyIconRpcCallback gNotifyIconCallback;
-#endif // G_PLATFORM_WIN32
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlugin::UnityPlugin --
- *
- * Constructor for the Unity plugin, initialized Unity, and common options
- * values.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-UnityPlugin::UnityPlugin(const ToolsAppCtx* ctx) // IN: The app context.
- : ToolsPlugin(ctx),
- mUnityUpdateChannel(NULL)
-{
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlugin::Initialize --
- *
- * Initializer for the Unity plugin, initialized Unity, and common options
- * values
- *
- * Results:
- * True if initializatino was successful.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-gboolean
-UnityPlugin::Initialize()
-{
- UnityHostCallbacks unityHostCallbacks;
- memset(&unityHostCallbacks, 0, sizeof unityHostCallbacks);
- unityHostCallbacks.buildUpdateCB = &UnityBuildUpdates;
- unityHostCallbacks.updateCB = &UnityUpdateCallbackFn;
- unityHostCallbacks.sendWindowContents = &UnitySendWindowContents;
- unityHostCallbacks.sendRequestMinimizeOperation = &UnitySendRequestMinimizeOperation;
- unityHostCallbacks.shouldShowTaskbar = &UnityShouldShowTaskbar;
- UnityTcloInit(mCtx->serviceObj);
-
- /*
- * Initialize the update channel.
- */
- mUnityUpdateChannel = UnityUpdateChannelInit();
- if (NULL == mUnityUpdateChannel) {
- Warning("%s: Unable to initialize Unity update channel.\n", __FUNCTION__);
- return false;
- }
- unityHostCallbacks.updateCbCtx = mUnityUpdateChannel;
-
- Unity_Init(unityHostCallbacks);
-
- GHITcloInit();
- GHIHostCallbacks ghiHostCallbacks;
- memset(&ghiHostCallbacks, 0, sizeof ghiHostCallbacks);
- ghiHostCallbacks.launchMenuChange = &GHILaunchMenuChangeRPC;
-
-#if defined(G_PLATFORM_WIN32)
- GHI_Init(mCtx->mainLoop, NULL, ghiHostCallbacks);
- GHI_RegisterNotifyIconCallback(&gNotifyIconCallback);
-#else
- GHI_Init(mCtx->mainLoop, mCtx->envp, ghiHostCallbacks);
-#endif // G_PLATFORM_WIN32
-
- if (g_key_file_get_boolean(mCtx->config, CONFGROUPNAME_UNITY,
- CONFNAME_UNITY_ENABLEDEBUG, NULL)) {
- Unity_InitializeDebugger();
- }
- Unity_SetForceEnable(g_key_file_get_boolean(mCtx->config, CONFGROUPNAME_UNITY,
- CONFNAME_UNITY_FORCEENABLE, NULL));
-
- /*
- * If no preferred color is in the config file then use a light gray tone,
- * the value is stored as xBGR.
- */
- int desktopColor = 0;
- GError *e = NULL;
- desktopColor = g_key_file_get_integer(mCtx->config, CONFGROUPNAME_UNITY,
- CONFNAME_UNITY_BACKGROUNDCOLOR, &e);
- if (e != NULL) {
- desktopColor = /* red */ 0xdc |
- /* green */ 0xdc << 8 |
- /* blue */ 0xdc << 16;
- }
- Unity_SetConfigDesktopColor(desktopColor);
- return true;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlugin::~UnityPlugin --
- *
- * Destructor for the Unity plugin, cleanup Unity.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Whole lotta stuff.
- *
- *-----------------------------------------------------------------------------
- */
-
-UnityPlugin::~UnityPlugin()
-{
- Unity_Cleanup();
- UnityUpdateChannelCleanup(mUnityUpdateChannel);
- UnityTcloCleanup();
-#if defined(G_PLATFORM_WIN32)
- GHI_UnregisterNotifyIconCallback(&gNotifyIconCallback);
-#endif // G_PLATFORM_WIN32
- GHI_Cleanup();
- GHITcloCleanup();
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlugin::GetCapabilities --
- *
- * Called by the service core when the host requests the capabilities
- * supported by the guest tools.
- *
- * Results:
- * A list of capabilities to be sent to the host.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-std::vector<ToolsAppCapability>
-UnityPlugin::GetCapabilities(gboolean set) // IN
-{
- /*
- * Note that we can't use UNITY_RPC_UNITY_CAP here because it includes the
- * "tools.capability" prefix which vmtoolsd will automatically prepend to the
- * supplied capability name.
- */
- Bool b = set ? Unity_IsSupported() : FALSE;
- std::vector<ToolsAppCapability> caps;
- caps.push_back(ToolsAppCapabilityOldEntry(UNITY_CAP_NAME, b));
- caps.push_back(ToolsAppCapabilityOldEntry("unity.taskbar", b));
- caps.push_back(ToolsAppCapabilityNewEntry(UNITY_CAP_STATUS_UNITY_ACTIVE, b));
- return caps;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlugin::GetRpcCallbackList --
- *
- * Called by the service core when the host requests the RPCs supported
- * by the guest tools.
- *
- * Results:
- * A list of RPC Callbacks to be sent to the host.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-std::vector<RpcChannelCallback>
-UnityPlugin::GetRpcCallbackList()
-{
- std::vector<RpcChannelCallback> rpcList;
-
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_ENTER, UnityTcloEnter));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_GET_UPDATE_FULL, UnityTcloGetUpdate));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_GET_UPDATE_INCREMENTAL, UnityTcloGetUpdate));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_GET_WINDOW_PATH, UnityTcloGetWindowPath));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_WINDOW_SETTOP, UnityTcloSetTopWindowGroup));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_GET_WINDOW_CONTENTS, UnityTcloGetWindowContents));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_GET_ICON_DATA, UnityTcloGetIconData));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_DESKTOP_WORK_AREA_SET, UnityTcloSetDesktopWorkArea));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_SHOW_TASKBAR, UnityTcloShowTaskbar));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_EXIT, UnityTcloExit));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_WINDOW_MOVE_RESIZE, UnityTcloMoveResizeWindow));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_DESKTOP_CONFIG_SET, UnityTcloSetDesktopConfig));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_DESKTOP_ACTIVE_SET, UnityTcloSetDesktopActive));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_WINDOW_DESKTOP_SET, UnityTcloSetWindowDesktop));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_CONFIRM_OPERATION, UnityTcloConfirmOperation));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_SET_OPTIONS, UnityTcloSetUnityOptions));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_WINDOW_CONTENTS_REQUEST, UnityTcloRequestWindowContents));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_SEND_MOUSE_WHEEL, UnityTcloSendMouseWheel));
-
- char **commandList = NULL;
- Unity_GetWindowCommandList(&commandList);
- for (int i = 0; commandList && (NULL != commandList[i]); i++) {
- rpcList.push_back(RpcChannelCallbackEntry(commandList[i], UnityTcloWindowCommand));
- }
-
- if (GHI_IsSupported()) {
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_GET_BINARY_INFO, GHITcloGetBinaryInfo));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_OPEN_LAUNCHMENU, GHITcloOpenStartMenu));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_GET_LAUNCHMENU_ITEM, GHITcloGetStartMenuItem));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_CLOSE_LAUNCHMENU, GHITcloCloseStartMenu));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_SHELL_OPEN, GHITcloShellOpen));
- rpcList.push_back(RpcChannelCallbackEntry(GHI_RPC_GUEST_SHELL_ACTION, GHITcloShellAction));
- rpcList.push_back(RpcChannelCallbackEntry(UNITY_RPC_GET_BINARY_HANDLERS, GHITcloGetBinaryHandlers));
- rpcList.push_back(RpcChannelCallbackEntry(GHI_RPC_SET_GUEST_HANDLER, GHITcloSetGuestHandler));
- rpcList.push_back(RpcChannelCallbackEntry(GHI_RPC_RESTORE_DEFAULT_GUEST_HANDLER, GHITcloRestoreDefaultGuestHandler));
- rpcList.push_back(RpcChannelCallbackEntry(GHI_RPC_OUTLOOK_SET_TEMP_FOLDER, GHITcloSetOutlookTempFolder));
- rpcList.push_back(RpcChannelCallbackEntry(GHI_RPC_OUTLOOK_RESTORE_TEMP_FOLDER, GHITcloRestoreOutlookTempFolder));
- rpcList.push_back(RpcChannelCallbackEntry(GHI_RPC_TRAY_ICON_SEND_EVENT, GHITcloTrayIconSendEvent));
- rpcList.push_back(RpcChannelCallbackEntry(GHI_RPC_TRAY_ICON_START_UPDATES, GHITcloTrayIconStartUpdates));
- rpcList.push_back(RpcChannelCallbackEntry(GHI_RPC_TRAY_ICON_STOP_UPDATES, GHITcloTrayIconStopUpdates));
- rpcList.push_back(RpcChannelCallbackEntry(GHI_RPC_SET_FOCUSED_WINDOW, GHITcloSetFocusedWindow));
- rpcList.push_back(RpcChannelCallbackEntry(GHI_RPC_GET_EXEC_INFO_HASH, GHITcloGetExecInfoHash));
- }
-
- return rpcList;
-}
-
-} /* namespace tools */ } /* namespace vmware */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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.
- *
- *********************************************************/
-
-/*
- * unityPlugin.h --
- *
- * Defines the object that implements the tools core service plugin form of
- * Unity.
- */
-
-#ifndef _UNITY_PLUGIN_H_
-#define _UNITY_PLUGIN_H_
-
-#include <string>
-#include <vector>
-
-#ifdef _WIN32
-#include "boost/shared_ptr.hpp"
-#endif // _WIN32
-
-#include "vmware/tools/plugin.h"
-
-namespace vmware { namespace tools {
-
-class UnityPBRPCServer;
-
-typedef struct _UnityUpdateChannel UnityUpdateChannel;
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * vmware::tools::RpcChannelCallbackEntry --
- *
- * Helper struct to build an RPCChannelCallback structure from a command
- * string and RpcIn_Callback.
- *
- *-----------------------------------------------------------------------------
- */
-
-struct RpcChannelCallbackEntry
- : public RpcChannelCallback
-{
- RpcChannelCallbackEntry(const char *RpcName, RpcIn_Callback func)
- {
- name = RpcName;
- callback = func;
- clientData = NULL;
- xdrIn = NULL;
- xdrOut = NULL;
- xdrInSize = 0;
- }
-};
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * vmware::tools::ToolsAppCapabilityOldEntry --
- *
- * Helper struct to build an ToolsAppCapability structure from an old
- * style capability name and flag to indicate whether the capability is
- * enabled.
- *
- *-----------------------------------------------------------------------------
- */
-
-struct ToolsAppCapabilityOldEntry
- : public ToolsAppCapability
-{
- ToolsAppCapabilityOldEntry(const char *capName, gboolean enabled)
- {
- type = TOOLS_CAP_OLD;
- /* The capability name field is not-const (though it seems to be treated that way)
- * so we'll need to cast away the const here 8-(
- */
- name = const_cast<gchar*>(capName);
- value = enabled;
- }
-};
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * vmware::tools::ToolsAppCapabilityNewEntry --
- *
- * Helper struct to build an ToolsAppCapability structure from a new style
- * capability index and flag to indicate whether the capability is enabled.
- *
- *-----------------------------------------------------------------------------
- */
-
-struct ToolsAppCapabilityNewEntry
- : public ToolsAppCapability
-{
- ToolsAppCapabilityNewEntry(GuestCapabilities cap, gboolean enabled)
- {
- type = TOOLS_CAP_NEW;
- name = NULL;
- index = cap;
- value = enabled;
- }
-};
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * vmware::tools::ToolsPlugin --
- *
- * Defines a pure virtual interface for plugins to implement. These
- * methods are called by per-plugin static C functions in the the plugin
- * entry module.
- *
- *-----------------------------------------------------------------------------
- */
-
-class ToolsPlugin {
-public:
- struct SignalCtx
- : public ToolsPluginSignalCb
- {
- SignalCtx(const char* signame_, void* callback_, void* clientData_)
- {
- signame = signame_;
- callback = callback_;
- clientData = clientData_;
- }
- };
-
- virtual ~ToolsPlugin() {};
-
- virtual gboolean Initialize() = 0;
- virtual gboolean Reset(gpointer src) = 0;
- virtual void Shutdown(gpointer src) = 0;
- virtual gboolean SetOption(gpointer src,
- const std::string &option,
- const std::string &value) = 0;
-
- virtual std::vector<ToolsAppCapability> GetCapabilities(gboolean set) = 0;
- virtual std::vector<RpcChannelCallback> GetRpcCallbackList() = 0;
- virtual std::vector<ToolsPluginSignalCb> GetSignalRegistrations(ToolsPluginData*) const;
-
-protected:
- ToolsPlugin(const ToolsAppCtx* ctx) : mCtx(ctx) {}
-
- // C thunks.
- static gboolean OnCReset(gpointer src, ToolsAppCtx* ctx, ToolsPluginData* pdata);
- static void OnCShutdown(gpointer src, ToolsAppCtx* ctx, ToolsPluginData* pdata);
- static GArray* OnCCapabilities(gpointer src, ToolsAppCtx* ctx, gboolean set,
- ToolsPluginData* plugin);
- static gboolean OnCSetOption(gpointer src, ToolsAppCtx* ctx, const gchar* option,
- const gchar* value, ToolsPluginData* plugin);
-
- const ToolsAppCtx* mCtx;
-};
-
-
-class UnityPlugin
- : public ToolsPlugin
-{
-public:
- virtual gboolean Initialize();
-
- virtual gboolean Reset(gpointer src) { return TRUE; }
- virtual void Shutdown(gpointer src) {};
- virtual gboolean SetOption(gpointer src,
- const std::string &option,
- const std::string &value)
- {
- return FALSE;
- }
-
- virtual std::vector<ToolsAppCapability> GetCapabilities(gboolean set);
- virtual std::vector<RpcChannelCallback> GetRpcCallbackList();
-
-protected:
- UnityPlugin(const ToolsAppCtx* ctx);
- virtual ~UnityPlugin();
-
- UnityUpdateChannel *mUnityUpdateChannel;
-};
-
-#ifdef _WIN32
-class UnityPluginWin32
- : public UnityPlugin
-{
-public:
- UnityPluginWin32(const ToolsAppCtx* ctx);
- virtual ~UnityPluginWin32();
-
- virtual gboolean Initialize();
-
- virtual std::vector<ToolsAppCapability> GetCapabilities(gboolean set);
- virtual std::vector<ToolsPluginSignalCb> GetSignalRegistrations(ToolsPluginData*) const;
-
- virtual DWORD OnServiceControl(gpointer src,
- ToolsAppCtx *ctx,
- SERVICE_STATUS_HANDLE handle,
- guint control,
- guint evtType,
- gpointer evtData);
-
- virtual void OnDesktopSwitch();
-
-protected:
- boost::shared_ptr<UnityPBRPCServer> mUnityPBRPCServer;
-
-private:
- static DWORD OnCServiceControl(gpointer src, ToolsAppCtx* ctx,
- SERVICE_STATUS_HANDLE handle, guint control,
- guint evtType, gpointer evtData,
- ToolsPluginData* data);
- static void OnCDesktopSwitch(gpointer src, ToolsAppCtx* ctx, ToolsPluginData* plugin);
-};
-#endif // _WIN32
-
-} /* namespace tools */ } /* namespace vmware */
-
-#endif // _UNITY_PLUGIN_H_
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * unityPluginEntry.cpp --
- *
- * Implements the unity plugin for the tools services. Registers for the Unity
- * RPC's and sets the Unity capabilities.
- *
- * XXX Rewrite all of this to match CUI models and be, like, readable.
- */
-
-#define G_LOG_DOMAIN "unity"
-
-#include "unityPlugin.h"
-
-#ifndef WIN32
-# include "unityPluginPosix.h"
-#endif
-
-extern "C" {
- #include "util.h"
- // guestrpc.h defines the RPCIn_Callback which is needed in rpcin.h which is in turn
- // included by unity.h - so guestrpc.h must precede unity.h
- #include "vmware/tools/guestrpc.h"
- #include "unity.h"
- #include "vmware/tools/plugin.h"
- #include "vmware/tools/utils.h"
-
- TOOLS_MODULE_EXPORT ToolsPluginData *ToolsOnLoad(ToolsAppCtx *ctx);
-};
-
-using namespace vmware::tools;
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsOnLoad --
- *
- * Plugin entry point. Returns the registration data.
- *
- * Results:
- * Registration data.
- *
- * Side effects:
- * XXX.
- *
- *-----------------------------------------------------------------------------
- */
-
-TOOLS_MODULE_EXPORT ToolsPluginData *
-ToolsOnLoad(ToolsAppCtx *ctx) // IN: The app context.
-{
- static ToolsPluginData regData = {
- "unity",
- NULL,
- NULL
- };
-
- if (ctx->rpc != NULL) {
- ToolsPlugin *pluginInstance = NULL;
-
-#if WIN32
- pluginInstance = new UnityPluginWin32(ctx);
-#else // Linux
- pluginInstance = new UnityPluginPosix(ctx);
-#endif
-
- if (!pluginInstance) {
- // There's nothing we can do if we can't construct the plugin instance
- return NULL;
- }
-
- if (!pluginInstance->Initialize()) {
- g_warning("%s: Unity Plugin failed to initialize.\n", __FUNCTION__);
- delete pluginInstance;
- return NULL;
- }
- regData._private = pluginInstance;
-
- std::vector<RpcChannelCallback> rpcs = pluginInstance->GetRpcCallbackList();
- std::vector<ToolsPluginSignalCb> sigs =
- pluginInstance->GetSignalRegistrations(®Data);
-
- ToolsAppReg regs[] = {
- { TOOLS_APP_GUESTRPC, VMTools_WrapArray(&rpcs[0], sizeof rpcs[0], rpcs.size()) },
- { TOOLS_APP_SIGNALS, VMTools_WrapArray(&sigs[0], sizeof sigs[0], sigs.size()) },
- };
-
- regData.regs = VMTools_WrapArray(regs, sizeof *regs, ARRAYSIZE(regs));
-
- return ®Data;
- }
-
- return NULL;
-}
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2011 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.
- *
- *********************************************************/
-
-/*
- * unityPluginPosix.cpp --
- *
- * POSIX subclass of UnityPlugin interface.
- */
-
-
-#include "unityPluginPosix.h"
-
-
-extern "C" {
-#include <glib-object.h>
-
-#include "vmware/tools/desktopevents.h"
-#if defined(OPEN_VM_TOOLS)
- #include "unitylib/unity.h"
-#else
- #include "unity.h"
-#endif // OPEN_VM_TOOLS
-}
-
-
-namespace vmware {
-namespace tools {
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPluginPosix::UnityPluginPosix --
- *
- * Constructor.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-UnityPluginPosix::UnityPluginPosix(const ToolsAppCtx* ctx) // IN: The app context.
- : UnityPlugin(ctx)
-{
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPluginPosix::~UnityPluginPosix --
- *
- * Destructor.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-UnityPluginPosix::~UnityPluginPosix()
-{
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPluginPosix::GetCapabilities --
- *
- * Called by the service core when the host requests the capabilities
- * supported by the guest tools.
- *
- * Results:
- * A list of capabilities to be sent to the host.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-std::vector<ToolsAppCapability>
-UnityPluginPosix::GetCapabilities(gboolean set) // IN
-{
- std::vector<ToolsAppCapability> caps = UnityPlugin::GetCapabilities(set);
-#define ADDCAP(capName) caps.push_back(ToolsAppCapabilityNewEntry(capName, set))
- ADDCAP(UNITY_CAP_WORK_AREA);
- ADDCAP(UNITY_CAP_START_MENU);
- ADDCAP(UNITY_CAP_MULTI_MON);
- ADDCAP(UNITY_CAP_VIRTUAL_DESK);
- ADDCAP(UNITY_CAP_STICKY_WINDOWS);
-#undef ADDCAP
- return caps;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPluginPosix::GetSignalRegistrations --
- *
- * Returns a vector containing signal registration info (signal name,
- * callback, callback context). Signals will be connected by container
- * after all plugins have successfully registered.
- *
- * Results:
- * Vector of signal registration info.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-std::vector<ToolsPluginSignalCb>
-UnityPluginPosix::GetSignalRegistrations(ToolsPluginData* pdata) // IN
- const
-{
- std::vector<ToolsPluginSignalCb> signals =
- UnityPlugin::GetSignalRegistrations(pdata);
- signals.push_back(
- ToolsPlugin::SignalCtx(TOOLS_CORE_SIG_XIOERROR, (void*)XIOErrorCb,
- static_cast<gpointer>(const_cast<UnityPluginPosix*>(this))));
- signals.push_back(
- ToolsPlugin::SignalCtx(TOOLS_CORE_SIG_XSM_DIE, (void*)XSMDieCb,
- static_cast<gpointer>(const_cast<UnityPluginPosix*>(this))));
- return signals;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPluginPosix::OnXSMDie --
- *
- * X Session Management event handler. Exits Unity upon notice of session
- * termination.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May trigger Unity exit.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityPluginPosix::OnXSMDie()
-{
- if (Unity_IsActive()) {
- Unity_Exit();
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPluginPosix::OnXIOError --
- *
- * In response to an X I/O error, signals host UI that vmusr is no longer
- * Unity-capable.
- *
- * This is done because we can't perform a full, correct clean-up after
- * receiving an X I/O error. See xioError.c for details.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Invokes a G->H RPC.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityPluginPosix::OnXIOError()
-{
- char *result;
- size_t resultLen;
- char tmp[] = "tools.capability.unity 0";
- RpcChannel_Send(mCtx->rpc, tmp, sizeof tmp, &result, &resultLen);
- vm_free(result);
-}
-
-
-/*
- ******************************************************************************
- * BEGIN Static member functions
- */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPluginPosix::XSMDieCb --
- *
- * Thunk between XSM "die" and OnXSMDie.
- *
- * Results:
- * None.
- *
- * Side effects:
- * See OnXSMDie.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityPluginPosix::XSMDieCb(GObject* obj, // UNUSED
- ToolsAppCtx* ctx, // UNUSED
- gpointer cbData) // IN: UnityPluginPosix*
-{
- UnityPluginPosix* unityPlugin = static_cast<UnityPluginPosix*>(cbData);
- unityPlugin->OnXSMDie();
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPluginPosix::XIOErrorCb --
- *
- * Thunk between XIOErrorHandler and OnXIOError.
- *
- * Results:
- * None.
- *
- * Side effects:
- * See OnXIOError.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityPluginPosix::XIOErrorCb(GObject* obj, // UNUSED
- ToolsAppCtx* ctx, // UNUSED
- gpointer cbData) // IN: UnityPluginPosix*
-{
- UnityPluginPosix* unityPlugin = static_cast<UnityPluginPosix*>(cbData);
- unityPlugin->OnXIOError();
-}
-
-
-/*
- * END Static member functions
- ******************************************************************************
- */
-
-
-} // namespace tools
-} // namespace vmware
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2011 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.
- *
- *********************************************************/
-
-/*
- * unityPluginPosix.h --
- *
- * POSIX subclass of UnityPlugin interface.
- */
-
-#ifndef UNITY_PLUGIN_POSIX_H
-#define UNITY_PLUGIN_POSIX_H
-
-#include <map>
-
-#include "unityPlugin.h"
-
-extern "C" {
-#include <glib-object.h>
-}
-
-
-namespace vmware {
-namespace tools {
-
-class UnityPluginPosix
- : public UnityPlugin
-{
-public:
- UnityPluginPosix(const ToolsAppCtx* ctx);
- virtual ~UnityPluginPosix();
-
- std::vector<ToolsAppCapability> GetCapabilities(gboolean set);
- std::vector<ToolsPluginSignalCb> GetSignalRegistrations(ToolsPluginData*) const;
-
-private:
- static void XSMDieCb(GObject*, ToolsAppCtx*, gpointer);
- void OnXSMDie();
-
- static void XIOErrorCb(GObject*, ToolsAppCtx*, gpointer);
- void OnXIOError();
-
- std::map<const char*, gulong> mSignalIDs;
-};
-
-
-} // namespace tools
-} // namespace vmware
-
-#endif // UNITY_PLUGIN_POSIX_H
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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 unityTclo.cpp
- *
- * Unity: Guest window manager integration service.
- *
- * This file implements parts of the guest-side Unity agent as part of the VMware Tools.
- * It contains entry points for the GuestRpc (TCLO, RPCI) interface.
- *
- * UnityWindowTracker updates are sent to the MKS in two ways:
- * @li @ref UNITY_RPC_GET_UPDATE GuestRpc (host-to-guest).
- * @li @ref UNITY_RPC_PUSH_UPDATE_CMD GuestRpc (guest-to-host).
- *
- * @note Looking for the old "unity.get.update" return syntax? See @ref
- * UNITY_RPC_GET_UPDATE and @ref UnityGetUpdateReturn instead.
- *
- * @sa
- * @li UnityRpcHG
- * @li UnityRpcGH
- */
-
-#include <glib.h>
-#include <glib-object.h>
-#include "vmware/tools/plugin.h"
-#include "vmware/tools/unityevents.h"
-
-extern "C" {
- #include "vmware.h"
- #include "conf.h"
- #include "debug.h"
- #include "dynxdr.h"
- #include "guestrpc/unity.h"
- #include "guestrpc/unityActive.h"
- #include "rpcin.h"
- #include "rpcout.h"
- #include "str.h"
- #include "strutil.h"
-#if defined(OPEN_VM_TOOLS)
- #include "unitylib/unity.h"
-#else
- #include "unity.h"
-#endif // OPEN_VM_TOOLS
- #include "unityDebug.h"
- #include "xdrutil.h"
-};
-
-#include "unityPlugin.h"
-#include "unityTclo.h"
-
-namespace vmware { namespace tools {
-
-/**
- * Container used to store and send Unity updates.
- */
-
-typedef struct _UnityUpdateChannel {
- DynBuf updates; ///< See @ref vmtools_unity_uwtGuestRpc.
- size_t cmdSize; /**< @brief Size of RpcOut command prefix.
- Used as a convenient offset within #updates when
- resetting the update buffer. */
- RpcOut *rpcOut;
-} UnityTCLOUpdateChannel;
-
-/*
- * Helper Functions
- */
-
-static Bool UnityUpdateState(void);
-
-/* Sends the unity.window.contents.start RPC to the host. */
-Bool UnitySendWindowContentsStart(UnityWindowId window,
- uint32 width,
- uint32 height,
- uint32 length);
-
-/* Sends the unity.window.contents.chunk RPC to the host. */
-Bool UnitySendWindowContentsChunk(UnityWindowId window,
- uint32 seq,
- const char *data,
- uint32 length);
-
-/* Sends the unity.window.contents.end RPC to the host. */
-Bool UnitySendWindowContentsEnd(UnityWindowId window);
-
-/*
- * Callback function used by UnityXdrSendRpc() to encode XDR-serialized
- * arguments.
- */
-typedef Bool(*UnityXdrEncodeFunc)(XDR*,void*);
-
-/*
- * Helper function used to send an RPC to the host with XDR-serialized
- * arguments. Calls encodeFn on the XDR* and the provied arg to perform
- * XDR encoding.
- */
-Bool UnityXdrSendRpc(const char *rpcName, UnityXdrEncodeFunc encodeFn, void *arg);
-
-/*
- * XXX:
- * According to Adar:
- * "UnityTcloGetUpdate cannot return the contents of a DynBuf. This will leak
- * the DynBuf's memory, since nobody at a lower level will ever free it. It's
- * a crappy interface, but we make due by using a static buffer to hold the
- * results."
- *
- * We ideally would not use a static buffer because the maximum size of the
- * update is unknown. To work around this, make the DynBuf returned in
- * UnityTcloGetUpdate file-global and recycle it across update requests.
- */
-
-static DynBuf gTcloUpdate;
-static gpointer gServiceObj = NULL;
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloInit --
- *
- * Initialize the global state (a Dynbuf) used to handle the TCLO parsing
- * and dispatch.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityTcloInit(gpointer serviceObj)
-{
- /*
- * Init our global dynbuf used to send results back.
- */
- DynBuf_Init(&gTcloUpdate);
-
- gServiceObj = serviceObj;
- g_signal_new(UNITY_SIG_ENTER_LEAVE_UNITY,
- G_OBJECT_TYPE(gServiceObj),
- (GSignalFlags) 0,
- 0,
- NULL,
- NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE,
- 1,
- G_TYPE_BOOLEAN);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloCleanup --
- *
- * Cleanup the global state (a Dynbuf) used to handle the TCLO parsing
- * and dispatch.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityTcloCleanup()
-{
- DynBuf_Destroy(&gTcloUpdate);
- gServiceObj = NULL;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloEnter --
- *
- * RPC handler for 'unity.enter'. Save and disable certain user
- * settings. Start Unity updates thread and any other platform
- * specific threads (like a thread that listens for
- * the desktop switch event on Windows). Note that we first set
- * the UI settings, and then start the threads. This way the UI
- * settings take effect before we start sending Unity updates,
- * so that we never send things like task bar (see bug 166085).
- *
- * Results:
- * TRUE if helper threads were started.
- * FALSE otherwise.
- *
- * Side effects:
- * Certain UI system settings will be disabled.
- * Unity update thread will be started.
- * Any other platform specific helper threads will be started as well.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloEnter(RpcInData *data) // IN/OUT
-{
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- Debug("%s\n", __FUNCTION__);
-
- if (!Unity_IsActive()) {
- if (!Unity_Enter()) {
- return RPCIN_SETRETVALS(data, "Could not enter unity", FALSE);
- }
-
- UnityUpdateState();
-
- if (NULL != gServiceObj) {
- g_signal_emit_by_name(gServiceObj, UNITY_SIG_ENTER_LEAVE_UNITY, TRUE);
- }
- }
-
- return RPCIN_SETRETVALS(data, "", TRUE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloExit --
- *
- * RPC handler for 'unity.exit'.
- *
- * Results:
- * Always TRUE.
- *
- * Side effects:
- * Same as side effects of Unity_Exit().
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloExit(RpcInData *data) // IN/OUT
-{
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- Debug("UnityTcloExit.\n");
-
- if (Unity_IsActive()) {
- Unity_Exit();
- UnityUpdateState();
-
- if (NULL != gServiceObj) {
- g_signal_emit_by_name(gServiceObj, UNITY_SIG_ENTER_LEAVE_UNITY, FALSE);
- }
- }
-
- return RPCIN_SETRETVALS(data, "", TRUE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloGetWindowPath --
- *
- * RPC handler for UNITY_RPC_GET_WINDOW_PATH.
- *
- * Get the information needed to re-launch a window and retrieve further
- * information on it. Returns double-NUL-terminated buffer consisting of
- * NUL-terminated strings "windowPath" and "execPath" strings, the first
- * uniquely identifying the window and the second uniquely identifying the
- * window's owning executable.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloGetWindowPath(RpcInData *data) // IN/OUT
-{
- UnityWindowId window;
- DynBuf windowPathUtf8;
- DynBuf execPathUtf8;
-
- unsigned int index = 0;
- Bool ret = TRUE;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- /* Parse the command & window id.*/
-
- if (!StrUtil_GetNextIntToken((int32*) &window, &index, data->args, " ")) {
- Debug("UnityTcloGetWindowInfo: Invalid RPC arguments.\n");
- return RPCIN_SETRETVALS(data,
- "Invalid arguments. Expected \"windowId\"",
- FALSE);
- }
-
- Debug("%s: window %d\n", __FUNCTION__, window);
-
- /*
- * Please note that the Unity_GetWindowPath implementations assume that the
- * dynbuf passed in does not contain any existing data that needs to be appended to,
- * so this code should continue to accomodate that assumption.
- */
- DynBuf_Destroy(&gTcloUpdate);
- DynBuf_Init(&gTcloUpdate);
- DynBuf_Init(&windowPathUtf8);
- DynBuf_Init(&execPathUtf8);
- if (!Unity_GetWindowPath(window, &windowPathUtf8, &execPathUtf8)) {
- Debug("%s: Could not get window path.\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data,
- "Could not get window path",
- FALSE);
- goto exit;
- }
-
- /*
- * Construct the buffer holding the result. Note that we need to use gTcloUpdate
- * here to avoid leaking during the RPC handler.
- */
- DynBuf_Copy(&windowPathUtf8, &gTcloUpdate);
- DynBuf_Append(&gTcloUpdate, DynBuf_Get(&execPathUtf8), DynBuf_GetSize(&execPathUtf8));
-
- /*
- * Write the final result into the result out parameters and return!
- */
- data->result = (char *)DynBuf_Get(&gTcloUpdate);
- data->resultLen = DynBuf_GetSize(&gTcloUpdate);
-
-exit:
- DynBuf_Destroy(&windowPathUtf8);
- DynBuf_Destroy(&execPathUtf8);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloWindowCommand --
- *
- * RPC handler for 'unity.window.*' (excluding 'unity.window.settop')
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloWindowCommand(RpcInData *data) // IN/OUT
-{
- UnityWindowId window;
- unsigned int index = 0;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("UnityTcloWindowCommand: name:%s args:'%s'\n", data->name, data->args);
-
- /* Parse the command & window id.*/
-
- if (!StrUtil_GetNextIntToken((int32*) &window, &index, data->args, " ")) {
- Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data,
- "Invalid arguments. Expected \"windowId\"",
- FALSE);
-
- }
-
- Debug("%s: %s window %d\n", __FUNCTION__, data->name, window);
-
- if (!Unity_WindowCommand(window, data->name)) {
- return RPCIN_SETRETVALS(data,
- "Could not execute window command",
- FALSE);
- } else {
- return RPCIN_SETRETVALS(data, "", TRUE);
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloSetDesktopWorkArea --
- *
- * RPC handler for 'unity.desktop.work_area.set'.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloSetDesktopWorkArea(RpcInData *data) // IN/OUT
-{
- Bool success = FALSE;
- const char *argList;
- unsigned int count;
- unsigned int i;
- UnityRect *workAreas = NULL;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- /*
- * The argument string will look something like:
- * <count> [ , <x> <y> <w> <h> ] * count.
- *
- * e.g.
- * 3 , 0 0 640 480 , 640 0 800 600 , 0 480 640 480
- */
-
- if (sscanf(data->args, "%u", &count) != 1) {
- return RPCIN_SETRETVALS(data,
- "Invalid arguments. Expected \"count\"",
- FALSE);
- }
-
- if (count != 0) {
- workAreas = (UnityRect *)malloc(sizeof *workAreas * count);
- if (!workAreas) {
- RPCIN_SETRETVALS(data,
- "Failed to alloc buffer for work areas",
- FALSE);
- goto out;
- }
- }
-
- for (argList = data->args, i = 0; i < count; i++) {
- argList = strchr(argList, ',');
- if (!argList) {
- RPCIN_SETRETVALS(data,
- "Expected comma separated display list",
- FALSE);
- goto out;
- }
- argList++; /* Skip past the , */
-
- if (sscanf(argList, " %d %d %d %d ",
- &workAreas[i].x, &workAreas[i].y,
- &workAreas[i].width, &workAreas[i].height) != 4) {
- RPCIN_SETRETVALS(data,
- "Expected x, y, w, h in display entry",
- FALSE);
- goto out;
- }
-
- if (workAreas[i].x < 0 || workAreas[i].y < 0 ||
- workAreas[i].width <= 0 || workAreas[i].height <= 0) {
- RPCIN_SETRETVALS(data, "Invalid argument", FALSE);
- goto out;
- }
- }
-
- if (!Unity_SetDesktopWorkAreas(workAreas, count)) {
- RPCIN_SETRETVALS(data,
- "Unity_SetDesktopWorkAreas failed",
- FALSE);
- goto out;
- }
-
- success = RPCIN_SETRETVALS(data, "", TRUE);
-
-out:
- free(workAreas);
- return success;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloSetTopWindowGroup --
- *
- * RPC handler for 'unity.window.settop'.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloSetTopWindowGroup(RpcInData *data) // IN/OUT
-{
- UnityWindowId window;
- unsigned int index = 0;
- unsigned int windowCount = 0;
- UnityWindowId windows[UNITY_MAX_SETTOP_WINDOW_COUNT];
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- /* Parse the command & window ids.*/
-
- while (StrUtil_GetNextUintToken(&window, &index, data->args, " ")) {
- windows[windowCount] = window;
- windowCount++;
- if (windowCount == UNITY_MAX_SETTOP_WINDOW_COUNT) {
- Debug("%s: Too many windows.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data,
- "Invalid arguments. Too many windows",
- FALSE);
- }
- }
-
- if (windowCount == 0) {
- Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data,
- "Invalid arguments. Expected at least one windowId",
- FALSE);
- }
-
- if (!Unity_SetTopWindowGroup(windows, windowCount)) {
- return RPCIN_SETRETVALS(data,
- "Could not execute window command",
- FALSE);
- }
-
- return RPCIN_SETRETVALS(data, "", TRUE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloGetUpdate --
- *
- * RPC handler for 'unity.get.update'. Ask the unity window tracker
- * to give us an update (either incremental or non-incremental based
- * on whether the 'incremental' arg is present) and send the result
- * back to the VMX.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Clearly.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloGetUpdate(RpcInData *data) // IN/OUT
-{
- Bool incremental = FALSE;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: name:%s args:'%s'", __FUNCTION__, data->name, data->args);
-
- /*
- * Specify incremental or non-incremetal updates based on whether or
- * not the client set the "incremental" arg.
- */
- if (strstr(data->name, "incremental")) {
- incremental = TRUE;
- }
-
- /*
- * Call into platform-specific implementation to gather and send updates
- * back via RPCI. (This is done to ensure all updates are sent to the
- * Unity server in sequence via the same channel.)
- */
- Unity_GetUpdate(incremental);
-
- /*
- * To maintain compatibility, we'll return a successful but empty response.
- */
- data->result = "";
- data->resultLen = 0;
-
- /*
- * Give the debugger a crack to do something interesting at this point
- *
- * XXX Not sure if this is worth keeping around since this routine no
- * longer returns updates directly.
- */
- UnityDebug_OnUpdate();
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloConfirmOperation --
- *
- * RPC handler for 'unity.operation.confirm'.
- *
- * Results:
- * TRUE if the confirmation could be handled sucessfully.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloConfirmOperation(RpcInData *data) // IN/OUT
-{
- UnityConfirmOperation unityConfirmOpMsg;
- UnityConfirmOperationV1 *confirmV1 = NULL;
- Bool retVal = FALSE;
- unsigned int ret;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: Enter.\n", __FUNCTION__);
-
- memset(&unityConfirmOpMsg, 0, sizeof unityConfirmOpMsg);
-
- /*
- * Deserialize the XDR data. Note that the data begins with args + 1 since
- * there is a space between the RPC name and the XDR serialization.
- */
- if (!XdrUtil_Deserialize(data->args + 1, data->argsSize - 1,
- (void *)xdr_UnityConfirmOperation, &unityConfirmOpMsg)) {
- ret = RPCIN_SETRETVALS(data, "Failed to deserialize data", FALSE);
- goto exit;
- }
-
- confirmV1 = unityConfirmOpMsg.UnityConfirmOperation_u.unityConfirmOpV1;
- retVal = Unity_ConfirmOperation(confirmV1->details.op,
- confirmV1->windowId,
- confirmV1->sequence,
- confirmV1->allow);
-
- /* Free any memory allocated by XDR - we're done with unityConfirmOpMsg */
- VMX_XDR_FREE(xdr_UnityConfirmOperation, &unityConfirmOpMsg);
- ret = RPCIN_SETRETVALS(data, "", retVal);
-
-exit:
- Debug("%s: Exit.\n", __FUNCTION__);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloSendMouseWheel --
- *
- * RPC handler for 'unity.sendMouseWheel'.
- *
- * Results:
- * TRUE on success, FALSE on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloSendMouseWheel(RpcInData *data) // IN/OUT
-{
- UnityMouseWheel unityMouseWheelMsg;
- UnityMouseWheelV1 *mouseWheelV1 = NULL;
- Bool retVal = FALSE;
- unsigned int ret;
- Debug("%s: Enter.\n", __FUNCTION__);
-
- memset(&unityMouseWheelMsg, 0, sizeof unityMouseWheelMsg);
-
- /*
- * Deserialize the XDR data. Note that the data begins with args + 1 since
- * there is a space between the RPC name and the XDR serialization.
- */
- if (!XdrUtil_Deserialize(data->args + 1, data->argsSize - 1,
- (void *)xdr_UnityMouseWheel, &unityMouseWheelMsg)) {
- ret = RPCIN_SETRETVALS(data, "Failed to deserialize data", FALSE);
- goto exit;
- }
-
- mouseWheelV1 = unityMouseWheelMsg.UnityMouseWheel_u.mouseWheelV1;
- retVal = Unity_SendMouseWheel(mouseWheelV1->deltaX,
- mouseWheelV1->deltaY,
- mouseWheelV1->deltaZ,
- mouseWheelV1->modifierFlags);
-
- /* Free any memory allocated by XDR - we're done with unityMouseWheelMsg */
- VMX_XDR_FREE(xdr_UnityMouseWheel, &unityMouseWheelMsg);
- ret = RPCIN_SETRETVALS(data, "", retVal);
-
-exit:
- Debug("%s: Exit.\n", __FUNCTION__);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityUpdateCallbackFn --
- *
- * Callback from the unity window tracker indicating something's
- * changed.
- *
- * Write the update string into our dynbuf accumlating the update
- * and return.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Clearly.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityUpdateCallbackFn(void *param, // IN: updateChannel
- UnityUpdate *update) // IN
-{
- UnityUpdateChannel *updateChannel = reinterpret_cast<UnityUpdateChannel *>(param);
- DynBuf *buf = NULL;
- char data[1024];
- int i, n, count = 0;
- RegionPtr region;
- char *titleUtf8 = NULL;
- char *windowPathUtf8 = "";
- char *execPathUtf8 = "";
-
- ASSERT(updateChannel);
- buf = &updateChannel->updates;
-
- switch (update->type) {
-
- case UNITY_UPDATE_ADD_WINDOW:
- if (DynBuf_GetSize(&update->u.addWindow.windowPathUtf8) > 0) {
- windowPathUtf8 =
- static_cast<char*>(DynBuf_Get(&update->u.addWindow.windowPathUtf8));
- }
- if (DynBuf_GetSize(&update->u.addWindow.execPathUtf8) > 0) {
- execPathUtf8 =
- static_cast<char*>(DynBuf_Get(&update->u.addWindow.execPathUtf8));
- }
-
- Str_Sprintf(data, sizeof data, "add %u windowPath=%s execPath=%s",
- update->u.addWindow.id,
- windowPathUtf8,
- execPathUtf8);
- DynBuf_AppendString(buf, data);
- break;
-
- case UNITY_UPDATE_MOVE_WINDOW:
- Str_Sprintf(data, sizeof data, "move %u %d %d %d %d",
- update->u.moveWindow.id,
- update->u.moveWindow.rect.x1,
- update->u.moveWindow.rect.y1,
- update->u.moveWindow.rect.x2,
- update->u.moveWindow.rect.y2);
- DynBuf_AppendString(buf, data);
- break;
-
- case UNITY_UPDATE_REMOVE_WINDOW:
- Str_Sprintf(data, sizeof data, "remove %u", update->u.removeWindow.id);
- DynBuf_AppendString(buf, data);
- break;
-
- case UNITY_UPDATE_CHANGE_WINDOW_REGION:
- /*
- * A null region indicates that the region should be deleted.
- * Make sure we write "region <id> 0" for the reply.
- */
- region = update->u.changeWindowRegion.region;
- if (region) {
- count = REGION_NUM_RECTS(region);
- }
- Str_Sprintf(data, sizeof data, "region %u %d",
- update->u.changeWindowRegion.id, count);
- DynBuf_AppendString(buf, data);
-
- for (i = 0; i < count; i++) {
- BoxPtr p = REGION_RECTS(region) + i;
- Str_Sprintf(data, sizeof data, "rect %d %d %d %d",
- p->x1, p->y1, p->x2, p->y2);
- DynBuf_AppendString(buf, data);
- }
- break;
-
- case UNITY_UPDATE_CHANGE_WINDOW_TITLE:
- titleUtf8 =
- reinterpret_cast<char*>(DynBuf_Get(&update->u.changeWindowTitle.titleUtf8));
-
- if (titleUtf8 &&
- (DynBuf_GetSize(&update->u.changeWindowTitle.titleUtf8) ==
- strlen(titleUtf8) + 1)) {
- Str_Sprintf(data, sizeof data, "title %u ",
- update->u.changeWindowTitle.id);
- Str_Strncat(data, sizeof data, titleUtf8, sizeof data - strlen(data) - 1);
- data[sizeof data - 1] = '\0';
- } else {
- Str_Sprintf(data, sizeof data, "title %u",
- update->u.changeWindowTitle.id);
- }
- DynBuf_AppendString(buf, data);
- break;
-
- case UNITY_UPDATE_CHANGE_ZORDER:
- n = Str_Snprintf(data, sizeof data, "zorder %d", update->u.zorder.count);
- DynBuf_Append(buf, data, n);
- for (unsigned int zOrderIndex = 0;
- zOrderIndex < update->u.zorder.count;
- zOrderIndex++) {
- n = Str_Snprintf(data, sizeof data, " %d", update->u.zorder.ids[zOrderIndex]);
- DynBuf_Append(buf, data, n);
- }
- DynBuf_AppendString(buf, ""); // for appending NULL
- break;
-
- case UNITY_UPDATE_CHANGE_WINDOW_STATE:
- Str_Sprintf(data, sizeof data, "state %u %u",
- update->u.changeWindowState.id,
- update->u.changeWindowState.state);
- DynBuf_AppendString(buf, data);
- break;
-
- case UNITY_UPDATE_CHANGE_WINDOW_ATTRIBUTE:
- Str_Sprintf(data, sizeof data, "attr %u %u %u",
- update->u.changeWindowAttribute.id,
- update->u.changeWindowAttribute.attr,
- update->u.changeWindowAttribute.value);
- DynBuf_AppendString(buf, data);
- break;
-
- case UNITY_UPDATE_CHANGE_WINDOW_TYPE:
- Str_Sprintf(data, sizeof data, "type %u %d",
- update->u.changeWindowType.id,
- update->u.changeWindowType.winType);
- DynBuf_AppendString(buf, data);
- break;
-
- case UNITY_UPDATE_CHANGE_WINDOW_ICON:
- Str_Sprintf(data, sizeof data, "icon %u %u",
- update->u.changeWindowIcon.id,
- update->u.changeWindowIcon.iconType);
- DynBuf_AppendString(buf, data);
- break;
-
- case UNITY_UPDATE_CHANGE_WINDOW_DESKTOP:
- Str_Sprintf(data, sizeof data, "desktop %u %d",
- update->u.changeWindowDesktop.id,
- update->u.changeWindowDesktop.desktopId);
- DynBuf_AppendString(buf, data);
- break;
-
- case UNITY_UPDATE_CHANGE_ACTIVE_DESKTOP:
- Str_Sprintf(data, sizeof data, "activedesktop %d",
- update->u.changeActiveDesktop.desktopId);
- DynBuf_AppendString(buf, data);
- break;
-
- default:
- NOT_IMPLEMENTED();
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityUpdateChannelInit --
- *
- * Initialize the state for the update channel.
- *
- * Return value:
- * Pointer to UpdateChannel structure or NULL
- *
- * Side effects:
- * RpcOut channel might be open.
- * Memory for the update buffer might be allocated.
- *
- *-----------------------------------------------------------------------------
- */
-
-UnityUpdateChannel *
-UnityUpdateChannelInit()
-{
- UnityUpdateChannel *updateChannel = NULL;
- updateChannel = reinterpret_cast<UnityUpdateChannel *>(Util_SafeCalloc(1, sizeof *updateChannel));
-
- DynBuf_Init(&updateChannel->updates);
- DynBuf_AppendString(&updateChannel->updates, UNITY_RPC_PUSH_UPDATE_CMD " ");
-
- /* Exclude the null. */
- updateChannel->cmdSize = DynBuf_GetSize(&updateChannel->updates) - 1;
- DynBuf_SetSize(&updateChannel->updates, updateChannel->cmdSize);
-
- updateChannel->rpcOut = RpcOut_Construct();
- if (updateChannel->rpcOut == NULL) {
- Warning("%s: RpcOut_Construct() failed\n", __FUNCTION__);
- goto error;
- }
-
- if (!RpcOut_start(updateChannel->rpcOut)) {
- Warning("%s: RpcOut_start() failed\n", __FUNCTION__);
- RpcOut_Destruct(updateChannel->rpcOut);
- goto error;
- }
-
- return updateChannel;
-
-error:
- DynBuf_Destroy(&updateChannel->updates);
- vm_free(updateChannel);
-
- return NULL;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityUpdateChannelCleanup --
- *
- * Cleanup the unity update channel.
- *
- * Return value:
- * None.
- *
- * Side effects:
- * RpcOut channel will be closed.
- * Memory will be freed.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityUpdateChannelCleanup(UnityUpdateChannel *updateChannel) // IN
-{
- if (updateChannel && updateChannel->rpcOut) {
- RpcOut_stop(updateChannel->rpcOut);
- RpcOut_Destruct(updateChannel->rpcOut);
- updateChannel->rpcOut = NULL;
-
- DynBuf_Destroy(&updateChannel->updates); // Avoid double-free by guarding this as well
- vm_free(updateChannel);
- }
-}
-
-
-#ifdef VMX86_DEVEL
-/*
- *-----------------------------------------------------------------------------
- *
- * DumpUpdate --
- *
- * Prints a Unity update via debug output. NUL is represented as '!'.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-DumpUpdate(UnityUpdateChannel *updateChannel) // IN
-{
- int i, len;
- char *buf = NULL;
-
- len = updateChannel->updates.size;
- buf = reinterpret_cast<char*>(Util_SafeMalloc(len + 1));
- memcpy(buf, updateChannel->updates.data, len);
- buf[len] = '\0';
- for (i = 0 ; i < len; i++) {
- if (buf[i] == '\0') {
- buf[i] = '!';
- }
- }
-
- Debug("%s: Sending update: %s\n", __FUNCTION__, buf);
-
- vm_free(buf);
-}
-#endif // ifdef VMX86_DEVEL
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnitySendUpdates --
- *
- * Send a round of unity updates. The caller is responsible
- * for gathering updates into updateChannel->updates buffer prior to the
- * function call. This function should only be called if there's data
- * in the update buffer to avoid sending empty update string to the VMX.
- *
- * Return value:
- * TRUE if the update was sent,
- * FALSE if something went wrong (an invalid RPC channel, for example).
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-UnitySendUpdates(void *param) // IN
-{
- char const *myReply;
- size_t myRepLen;
- Bool retry = FALSE;
- UnityUpdateChannel *updateChannel = reinterpret_cast<UnityUpdateChannel*>(param);
-
- ASSERT(updateChannel);
- ASSERT(updateChannel->rpcOut);
-
- /* Send 'tools.unity.push.update <updates>' to the VMX. */
-
-#ifdef VMX86_DEVEL
- DumpUpdate(updateChannel);
-#endif
-
-retry_send:
- if (!RpcOut_send(updateChannel->rpcOut,
- (char *)DynBuf_Get(&updateChannel->updates),
- DynBuf_GetSize(&updateChannel->updates),
- &myReply, &myRepLen)) {
-
- /*
- * We could not send the RPC. If we haven't tried to reopen
- * the channel, try to reopen and resend. If we already
- * tried to resend, then it's time to give up. I hope that
- * trying to resend once is enough.
- */
-
- if (!retry) {
- retry = TRUE;
- Debug("%s: could not send rpc. Reopening channel.\n", __FUNCTION__);
- RpcOut_stop(updateChannel->rpcOut);
- if (!RpcOut_start(updateChannel->rpcOut)) {
- Debug("%s: could not reopen rpc channel. Exiting...\n", __FUNCTION__);
- return FALSE;
- }
- goto retry_send;
-
- } else {
- Debug("%s: could not resend rpc. Giving up and exiting...\n", __FUNCTION__);
- return FALSE;
- }
- }
-
- /*
- * With the update queue sent, purge the DynBuf by trimming it to the length
- * of the command preamble.
- */
- DynBuf_SetSize(&updateChannel->updates, updateChannel->cmdSize);
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloGetWindowContents --
- *
- * RPC handler for 'unity.get.window.contents'. Suck the bits off the
- * window and return a .png image over the backdoor.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloGetWindowContents(RpcInData *data) // IN/OUT
-{
- unsigned int window;
- unsigned int index = 0;
- DynBuf *imageData = &gTcloUpdate;
- uint32 width;
- uint32 height;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- /*
- * Parse the command & window id.
- */
- if (!StrUtil_GetNextIntToken((int32*) &window, &index, data->args, " ")) {
- Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data,
- "failed: arguments. Expected \"windowId\"",
- FALSE);
-
- }
- Debug("%s: window %d\n", __FUNCTION__, window);
-
- /*
- * Read the contents of the window, compress it as a .png and
- * send the .png back to the vmx as the RPC result.
- */
- DynBuf_SetSize(imageData, 0);
- if (!Unity_GetWindowContents(window, imageData, &width, &height)) {
- return RPCIN_SETRETVALS(data,
- "failed: Could not read window contents",
- FALSE);
- }
-
- data->result = (char *)DynBuf_Get(imageData);
- data->resultLen = DynBuf_GetSize(imageData);
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloGetIconData --
- *
- * RPC handler for 'unity.get.icon.data'. Suck the bits off the
- * window and return a .png image over the backdoor.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloGetIconData(RpcInData *data) // IN/OUT
-{
- UnityWindowId window;
- UnityIconType iconType;
- UnityIconSize iconSize;
- unsigned int dataOffset, dataLength;
- uint32 fullLength;
- size_t retLength;
- DynBuf *results = &gTcloUpdate, imageData;
- char bitmapData[1024];
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- /*
- * Parse the arguments.
- */
- if ((sscanf(data->args, "%u %u %u %u %u",
- &window,
- (unsigned int*) &iconType,
- &iconSize,
- &dataOffset,
- &dataLength) != 5)
- || (dataLength > UNITY_MAX_ICON_DATA_CHUNK)) {
- Debug("UnityTcloGetIconData: Invalid RPC arguments.\n");
- return RPCIN_SETRETVALS(data,
- "failed: arguments missing",
- FALSE);
- }
-
- Debug("%s: window %u iconType %u" \
- " iconSize %u dataOffset %u dataLength %u\n",
- __FUNCTION__,
- window, iconType, iconSize, dataOffset, dataLength);
-
- /*
- * Retrieve part/all of the icon in PNG format.
- */
- DynBuf_Init(&imageData);
- if (!Unity_GetIconData(window, iconType, iconSize,
- dataOffset, dataLength, &imageData, &fullLength)) {
- return RPCIN_SETRETVALS(data,
- "failed: Could not read icon data properly",
- FALSE);
- }
-
-
- DynBuf_SetSize(results, 0);
- retLength = DynBuf_GetSize(&imageData);
- retLength = MIN(retLength, UNITY_MAX_ICON_DATA_CHUNK);
- DynBuf_Append(results, bitmapData, Str_Snprintf(bitmapData,
- sizeof bitmapData,
- "%u %" FMTSZ "u ",
- fullLength, retLength));
- DynBuf_Append(results, DynBuf_Get(&imageData), retLength);
-
- /*
- * Guarantee that the results have a trailing \0 in case anything does a strlen...
- */
- DynBuf_AppendString(results, "");
- data->result = (char *)DynBuf_Get(results);
- data->resultLen = DynBuf_GetSize(results);
- DynBuf_Destroy(&imageData);
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloShowTaskbar --
- *
- * RPC handler for 'unity.show.taskbar'.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloShowTaskbar(RpcInData *data) // IN/OUT
-{
- uint32 command = 0;
- unsigned int index = 0;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- if (!StrUtil_GetNextUintToken(&command, &index, data->args, " ")) {
- Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data,
- "Invalid arguments.",
- FALSE);
- }
-
- Debug("%s: command %d\n", __FUNCTION__, command);
-
- Unity_ShowTaskbar((command == 0) ? FALSE : TRUE);
-
- return RPCIN_SETRETVALS(data, "", TRUE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloMoveResizeWindow --
- *
- * RPC handler for 'unity.window.move_resize'.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- * If successful adds null terminated strings for each output coordinates.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloMoveResizeWindow(RpcInData *data) // IN/OUT
-{
- DynBuf *buf = &gTcloUpdate;
- UnityWindowId window;
- UnityRect moveResizeRect = {0};
- char temp[1024];
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- if (sscanf(data->args, "%u %d %d %d %d",
- &window,
- &moveResizeRect.x,
- &moveResizeRect.y,
- &moveResizeRect.width,
- &moveResizeRect.height) != 5) {
- Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data,
- "Invalid arguments.",
- FALSE);
- }
-
- if (!Unity_MoveResizeWindow(window, &moveResizeRect)) {
- Debug("%s: Could not read window coordinates.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data,
- "Could not read window coordinates",
- FALSE);
- }
-
- /*
- * Send back the new (post move/resize operation) window coordinates.
- */
-
- DynBuf_SetSize(buf, 0);
- Str_Sprintf(temp, sizeof temp, "%d %d %d %d", moveResizeRect.x,
- moveResizeRect.y, moveResizeRect.width, moveResizeRect.height);
- DynBuf_AppendString(buf, temp);
-
- /*
- * Write the final result into the result out parameters and return!
- */
-
- data->result = (char *)DynBuf_Get(buf);
- data->resultLen = DynBuf_GetSize(buf);
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloSetDesktopConfig --
- *
- * RPC handler for 'unity.set.desktop.config'. The RPC takes the form of:
- * {1,1} {1,2} {2,1} {2,2} 1
- * for a 2 x 2 virtual desktop where the upper right {1,2} is the currently
- * active desktop.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * Might change virtual desktop configuration in the guest.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloSetDesktopConfig(RpcInData *data) // IN/OUT
-{
- unsigned int index = 0;
- char *desktopStr = NULL;
- char *errorMsg;
- uint32 initialDesktopIndex = 0;
- UnityVirtualDesktopArray desktopConfig;
-
- memset(&desktopConfig, 0, sizeof desktopConfig);
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- if (data->argsSize == 0) {
- errorMsg = "Invalid arguments: desktop config is expected";
- goto error;
- }
-
- /* Read the virtual desktop configuration. */
- while ((desktopStr = StrUtil_GetNextToken(&index, data->args, " ")) != NULL) {
-
- if (sscanf(desktopStr, "{%d,%d}",
- &desktopConfig.desktops[desktopConfig.desktopCount].x,
- &desktopConfig.desktops[desktopConfig.desktopCount].y) == 2) {
- if (desktopConfig.desktopCount >= MAX_VIRT_DESK - 1) {
- errorMsg = "Invalid arguments: too many desktops";
- goto error;
- }
- desktopConfig.desktopCount++;
- } else if (sscanf(desktopStr, "%u", &initialDesktopIndex) == 1) {
- if (initialDesktopIndex >= desktopConfig.desktopCount) {
- errorMsg = "Invalid arguments: current desktop is out of bounds";
- goto error;
- }
- /* All done with arguments at this point - stop processing */
- free(desktopStr);
- break;
- } else {
- errorMsg = "Invalid arguments: invalid desktop config";
- goto error;
- }
- free(desktopStr);
- desktopStr = NULL;
- }
-
- /*
- * Call the platform specific function to set the desktop configuration.
- */
-
- if (!Unity_SetDesktopConfig(&desktopConfig)) {
- errorMsg = "Could not set desktop configuration";
- goto error;
- }
-
- if (!Unity_SetInitialDesktop(initialDesktopIndex)) {
- errorMsg = "Could not set initial desktop";
- goto error;
- }
-
- return RPCIN_SETRETVALS(data,
- "",
- TRUE);
-error:
- free(desktopStr);
- Debug("%s: %s\n", __FUNCTION__, errorMsg);
-
- return RPCIN_SETRETVALS(data,
- errorMsg,
- FALSE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloSetDesktopActive --
- *
- * RPC handler for 'unity.set.desktop.active'.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * Might change the active virtual desktop in the guest.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloSetDesktopActive(RpcInData *data) // IN/OUT
-{
- UnityDesktopId desktopId = 0;
- char *errorMsg;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- if (Unity_IsActive() == FALSE) {
- errorMsg = "Unity not enabled - cannot change active desktop";
- goto error;
- }
-
- if (sscanf(data->args, " %d", &desktopId) != 1) {
- errorMsg = "Invalid arguments: expected \"desktopId\"";
- goto error;
- }
-
- /*
- * Call the platform specific function to set the desktop active.
- */
-
- if (!Unity_SetDesktopActive(desktopId)) {
- errorMsg = "Could not set active desktop";
- goto error;
- }
-
- return RPCIN_SETRETVALS(data,
- "",
- TRUE);
-error:
- Debug("%s: %s\n", __FUNCTION__, errorMsg);
- return RPCIN_SETRETVALS(data,
- errorMsg,
- FALSE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloSetWindowDesktop --
- *
- * RPC handler for 'unity.set.window.desktop'.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * Might change the active virtual desktop in the guest.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloSetWindowDesktop(RpcInData *data) // IN/OUT
-{
- UnityWindowId windowId;
- uint32 desktopId = 0;
- char *errorMsg;
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
-
- if (Unity_IsActive() == FALSE) {
- errorMsg = "Unity not enabled - cannot set window desktop";
- goto error;
- }
-
- if (sscanf(data->args, " %u %d", &windowId, &desktopId) != 2) {
- errorMsg = "Invalid arguments: expected \"windowId desktopId\"";
- goto error;
- }
-
- /*
- * Call the platform specific function to move the window to the
- * specified desktop.
- */
-
- if (!Unity_SetWindowDesktop(windowId, desktopId)) {
- errorMsg = "Could not move the window to the desktop";
- goto error;
- }
-
- return RPCIN_SETRETVALS(data,
- "",
- TRUE);
-error:
- Debug("%s: %s\n", __FUNCTION__, errorMsg);
- return RPCIN_SETRETVALS(data,
- errorMsg,
- FALSE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloSetUnityOptions --
- *
- * Set the Unity options - must be be called before entering Unity mode.
- *
- * Results:
- * TRUE if RPC was succesfully handled.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloSetUnityOptions(RpcInData *data)
-{
- Bool ret = TRUE;
- UnityOptions optionsMsg;
-
- memset(&optionsMsg, 0, sizeof optionsMsg);
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: Got RPC, name: \"%s\", argument length: %"FMTSZ"u.\n",
- __FUNCTION__, data->name, data->argsSize);
-
- /*
- * Deserialize the XDR data. Note that the data begins with args + 1 since
- * there is a space between the RPC name and the XDR serialization.
- */
- if (!XdrUtil_Deserialize((char *)data->args + 1, data->argsSize - 1,
- (void *)xdr_UnityOptions, &optionsMsg)) {
- Debug("%s: Failed to deserialize data\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data, "Failed to deserialize data.", FALSE);
- goto exit;
- }
-
- Unity_SetUnityOptions(optionsMsg.UnityOptions_u.unityOptionsV1->featureMask);
-
- ret = RPCIN_SETRETVALS(data,
- "",
- TRUE);
-exit:
- VMX_XDR_FREE(xdr_UnityOptions, &optionsMsg);
-
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityTcloRequestWindowContents --
- *
- * Request the window contents for a set of windows.
- *
- * Results:
- * TRUE if all the window IDs are valid.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-gboolean
-UnityTcloRequestWindowContents(RpcInData *data) // IN
-{
- Bool ret = TRUE;
- UnityWindowContentsRequest requestMsg;
- UnityWindowContentsRequestV1 *requestV1 = NULL;
- memset(&requestMsg, 0, sizeof requestMsg);
-
- /* Check our arguments. */
- ASSERT(data);
- if (!data) {
- return FALSE;
- }
-
- ASSERT(data->name);
- ASSERT(data->args);
-
- if (!data->name || !data->args) {
- Debug("%s: Invalid arguments.\n", __FUNCTION__);
- return RPCIN_SETRETVALS(data, "Invalid arguments.", FALSE);
- }
-
- Debug("%s: Got RPC, name: \"%s\", argument length: %"FMTSZ"u.\n",
- __FUNCTION__, data->name, data->argsSize);
-
- /*
- * Deserialize the XDR data. Note that the data begins with args + 1 since
- * there is a space between the RPC name and the XDR serialization.
- */
- if (!XdrUtil_Deserialize((char *)data->args + 1, data->argsSize - 1,
- (void *)xdr_UnityWindowContentsRequest, &requestMsg)) {
- Debug("%s: Failed to deserialize data\n", __FUNCTION__);
- ret = RPCIN_SETRETVALS(data, "Failed to deserialize data.", FALSE);
- goto exit;
- }
-
- if (requestMsg.ver != UNITY_WINDOW_CONTENTS_V1) {
- Debug("%s: Unexpected XDR version = %d\n", __FUNCTION__, requestMsg.ver);
- goto exit;
- }
-
- requestV1 = requestMsg.UnityWindowContentsRequest_u.requestV1;
-
- /*
- * Call the platform implementation of the RPC handler.
- */
- if (!Unity_RequestWindowContents(requestV1->windowID.windowID_val,
- requestV1->windowID.windowID_len)) {
- ret = RPCIN_SETRETVALS(data, "Invalid list of windows.", FALSE);
- goto exit;
- }
-
- ret = RPCIN_SETRETVALS(data,
- "",
- TRUE);
-exit:
- VMX_XDR_FREE(xdr_UnityWindowContentsRequest, &requestMsg);
-
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityUpdateState --
- *
- * Communicate unity state changes to vmx.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-UnityUpdateState(void)
-{
- Bool ret = TRUE;
- XDR xdrs;
- UnityActiveProto message;
- char *val;
-
- if (DynXdr_Create(&xdrs) == NULL) {
- return FALSE;
- }
-
- val = Str_Asprintf(NULL, "%s ", UNITY_RPC_UNITY_ACTIVE);
- if (!val || !DynXdr_AppendRaw(&xdrs, val, strlen(val))) {
- Debug("%s: Failed to create state string.\n", __FUNCTION__);
- ret = FALSE;
- goto out;
- }
- memset(&message, 0, sizeof message);
- message.ver = UNITY_ACTIVE_V1;
- message.UnityActiveProto_u.unityActive = Unity_IsActive();
- if (!xdr_UnityActiveProto(&xdrs, &message)) {
- Debug("%s: Failed to append message content.\n", __FUNCTION__);
- ret = FALSE;
- goto out;
- }
-
- if (!RpcOut_SendOneRaw(DynXdr_Get(&xdrs), xdr_getpos(&xdrs), NULL, NULL)) {
- Debug("%s: Failed to send Unity state RPC.\n", __FUNCTION__);
- ret = FALSE;
- } else {
- Debug("%s: success\n", __FUNCTION__);
- }
-out:
- free(val);
- DynXdr_Destroy(&xdrs, TRUE);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityXdrRequestOperation --
- *
- * XDR encoder function for UnityRequestOperation.
- *
- * See UnityXdrSendRpc().
- *
- * Results:
- * Returns true if the XDR struct was encoded successfully.
- *
- * Side-effects:
- * None.
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityXdrRequestOperation(XDR *xdrs, // IN
- void *arg) // IN
-{
- ASSERT(xdrs);
- ASSERT(arg);
- return xdr_UnityRequestOperation(xdrs, (UnityRequestOperation *) arg);
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnitySendRequestMinimizeOperation --
- *
- * Send a request for a minimize operation to the host.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnitySendRequestMinimizeOperation(UnityWindowId windowId, // IN
- uint32 sequence) // IN
-{
- Bool ret = FALSE;
- UnityRequestOperation msg;
- UnityRequestOperationV1 v1;
- memset(&msg, 0, sizeof msg);
- memset(&v1, 0, sizeof v1);
-
- Debug("%s: Enter.\n", __FUNCTION__);
-
- v1.windowId = windowId;
- v1.sequence = sequence;
- v1.details.op = MINIMIZE;
-
- msg.ver = UNITY_OP_V1;
- msg.UnityRequestOperation_u.unityRequestOpV1 = &v1;
-
- ret = UnityXdrSendRpc(UNITY_RPC_REQUEST_OPERATION,
- &UnityXdrRequestOperation,
- &msg);
-
- Debug("%s: Exit.\n", __FUNCTION__);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnitySendWindowContents --
- *
- * Sends the content of a window to the host, as a PNG encoded image. If the
- * image is larger than the maximum size of a GuestMsg, this function breaks
- * the image down into a number of chunks, then transfers each of the chunks
- * independently. See guest_msg_def.h and unity.x.
- *
- * Results:
- * Returns true if the image was transferred successfully.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnitySendWindowContents(UnityWindowId windowID, // IN
- uint32 imageWidth, // IN
- uint32 imageHeight, // IN
- const char *imageData, // IN
- uint32 imageLength) // IN
-{
- Bool ret = FALSE;
- uint32 count = 0; /* count of chunks sent */
- uint32 len = 0; /* length of the next chunk */
- const char *readptr = imageData; /* pointer to start of next chunk in imageData */
-
- ASSERT(imageWidth > 0);
- ASSERT(imageHeight > 0);
- ASSERT(imageLength > 0);
- ASSERT(imageData);
-
- Debug("%s: Enter.\n", __FUNCTION__);
- Debug("%s: Sending contents of window 0x%x.\n", __FUNCTION__, windowID);
- Debug("%s: Contents are (%u x %u) image, %u bytes.\n", __FUNCTION__,
- imageWidth, imageHeight, imageLength);
-
- /* Send the unity.window.contents.start RPC to the host. */
- if (!UnitySendWindowContentsStart(windowID,
- imageWidth,
- imageHeight,
- imageLength)) {
- goto exit;
- }
-
- /* Send the image data. */
- while (imageLength > 0) {
- /*
- * Get the length of the next chunk to send, up to a maximum of
- * UNITY_WINDOW_CONTENTS_MAX_CHUNK_SIZE bytes.
- */
- len = MIN(UNITY_WINDOW_CONTENTS_MAX_CHUNK_SIZE, imageLength);
-
- Debug("%s: Sending chunk %u at offset 0x%p, size %u.\n", __FUNCTION__,
- count, readptr, len);
-
- /* Send the next chunk to the host. */
- if (!UnitySendWindowContentsChunk(windowID, count, readptr, len)) {
- goto exit;
- }
-
- count++;
- readptr += len;
- imageLength -= len;
- }
-
- /* Send the unity.window.contents.end RPC to the host. */
- if (!UnitySendWindowContentsEnd(windowID)) {
- goto exit;
- }
-
- ret = TRUE;
-
-exit:
- return ret;
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityXdrEncodeWindowContentsStart --
- *
- * XDR encoder function for UnityWindowContentsStart.
- *
- * See UnityXdrSendRpc().
- *
- * Results:
- * Returns true if the XDR struct was encoded successfully.
- *
- * Side effects:
- * None.
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityXdrEncodeWindowContentsStart(XDR *xdrs,
- void *arg)
-{
- ASSERT(xdrs);
- ASSERT(arg);
- return xdr_UnityWindowContentsStart(xdrs, (UnityWindowContentsStart *) arg);
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnitySendWindowContentsStart --
- *
- * Sends the unity.window.contents.start RPC to the host.
- *
- * Results:
- * Returns true if the RPC was sent successfully.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnitySendWindowContentsStart(UnityWindowId windowID, // IN
- uint32 imageWidth, // IN
- uint32 imageHeight, // IN
- uint32 imageLength) // IN
-{
- Bool ret = FALSE;
- UnityWindowContentsStart msg;
- UnityWindowContentsStartV1 v1;
-
- memset(&msg, 0, sizeof msg);
- memset(&v1, 0, sizeof v1);
-
- Debug("%s: Enter.\n", __FUNCTION__);
-
- v1.windowID = windowID;
- v1.imageWidth = imageWidth;
- v1.imageHeight = imageHeight;
- v1.imageLength = imageLength;
-
- msg.ver = UNITY_WINDOW_CONTENTS_V1;
- msg.UnityWindowContentsStart_u.startV1 = &v1;
-
- ret = UnityXdrSendRpc(UNITY_RPC_WINDOW_CONTENTS_START,
- &UnityXdrEncodeWindowContentsStart,
- &msg);
-
- Debug("%s: Exit.\n", __FUNCTION__);
- return ret;
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityXdrEncodeWindowContentsChunk --
- *
- * XDR encoder function for UnityWindowContentsChunk.
- *
- * See UnityXdrSendRpc().
- *
- * Results:
- * Returns true if the XDR struct was encoded successfully.
- *
- * Side-effects:
- * None.
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityXdrEncodeWindowContentsChunk(XDR *xdrs,
- void *arg)
-{
- ASSERT(xdrs);
- ASSERT(arg);
- return xdr_UnityWindowContentsChunk(xdrs, (UnityWindowContentsChunk *) arg);
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnitySendWindowContentsChunk --
- *
- * Sends a unity.window.contents.chunk RPC to the host.
- *
- * Results:
- * Returns true if the RPC was sent successfully.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnitySendWindowContentsChunk(UnityWindowId windowID,
- uint32 chunkID,
- const char *data,
- uint32 len)
-{
- Bool ret = FALSE;
- UnityWindowContentsChunk msg;
- UnityWindowContentsChunkV1 v1;
- memset(&msg, 0, sizeof msg);
- memset(&v1, 0, sizeof v1);
-
- Debug("%s: Enter.\n", __FUNCTION__);
-
- v1.windowID = windowID;
- v1.chunkID = chunkID;
- v1.data.data_val = (char *) data;
- v1.data.data_len = len;
-
- msg.ver = UNITY_WINDOW_CONTENTS_V1;
- msg.UnityWindowContentsChunk_u.chunkV1 = &v1;
-
- ret = UnityXdrSendRpc(UNITY_RPC_WINDOW_CONTENTS_CHUNK,
- &UnityXdrEncodeWindowContentsChunk,
- &msg);
-
- Debug("%s: Exit.\n", __FUNCTION__);
- return ret;
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityXdrEncodeWindowContentsEnd --
- *
- * XDR encoder function for UnityWindowContentsEnd.
- *
- * Results:
- * Returns true if the XDR struct was encoded successfully.
- *
- * Side effects:
- * None.
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityXdrEncodeWindowContentsEnd(XDR *xdrs,
- void *arg)
-{
- ASSERT(xdrs);
- ASSERT(arg);
- return xdr_UnityWindowContentsEnd(xdrs, (UnityWindowContentsEnd*) arg);
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnitySendWindowContentsEnd --
- *
- * Sends a unity.window.contents.end RPC to the host.
- *
- * Results:
- * Returns true if the RPC was sent successfully.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnitySendWindowContentsEnd(UnityWindowId windowID)
-{
- Bool ret = FALSE;
- UnityWindowContentsEnd msg;
- UnityWindowContentsEndV1 v1;
- memset(&msg, sizeof msg, 0);
- memset(&v1, sizeof v1, 0);
-
- Debug("%s: Enter.\n", __FUNCTION__);
-
- v1.windowID = windowID;
-
- msg.ver = UNITY_WINDOW_CONTENTS_V1;
- msg.UnityWindowContentsEnd_u.endV1 = &v1;
-
- ret = UnityXdrSendRpc(UNITY_RPC_WINDOW_CONTENTS_END,
- &UnityXdrEncodeWindowContentsEnd,
- &msg);
-
- Debug("%s: Exit.\n", __FUNCTION__);
- return ret;
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityXdrSendRpc --
- *
- * Sends an RPC with XDR-serialized arguments to the host. The provided
- * encodeFn will be called to perform XDR encoding of the RPC, with the XDR
- * struct and the provided data pointer as its parameters.
- *
- * Returns:
- * True if the RPC was sent successfully.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityXdrSendRpc(const char *rpcName,
- UnityXdrEncodeFunc encodeFn,
- void *data)
-{
- Bool ret = FALSE;
- XDR xdrs;
- memset(&xdrs, 0, sizeof xdrs);
-
- ASSERT(rpcName);
-
- Debug("%s: Enter.\n", __FUNCTION__);
-
- if (!DynXdr_Create(&xdrs)) {
- Debug("%s: Failed to create DynXdr.\n", __FUNCTION__);
- goto exit;
- }
-
- if (!DynXdr_AppendRaw(&xdrs, rpcName, strlen(rpcName))) {
- Debug("%s: Failed to append RPC name to DynXdr.\n", __FUNCTION__);
- goto dynxdr_destroy;
- }
-
- if (!DynXdr_AppendRaw(&xdrs, " ", 1)) {
- Debug("%s: Failed to append space to DynXdr.\n", __FUNCTION__);
- goto dynxdr_destroy;
- }
-
- if (!(*encodeFn)(&xdrs, data)) {
- Debug("%s: Failed to serialize RPC data.\n", __FUNCTION__);
- goto dynxdr_destroy;
- }
-
- if (!RpcOut_SendOneRaw(DynXdr_Get(&xdrs), xdr_getpos(&xdrs), NULL, NULL)) {
- Debug("%s: Failed to send RPC.\n", __FUNCTION__);
- goto dynxdr_destroy;
- }
-
- ret = TRUE;
-
-dynxdr_destroy:
- DynXdr_Destroy(&xdrs, TRUE);
-
-exit:
- Debug("%s: Exit.\n", __FUNCTION__);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityBuildUpdates --
- *
- * Gather a round of Unity Updates from the Window Tracker. Initialize our
- * dynbuf used to hold the updates, call to get the updates into our channel
- * and add the terminating NULL. If updates were added to the buffer send them
- * to the host.
- *
- * Results:
- * TRUE if updates were added to the buffer and succesfully sent to the host.
- *
- * Side effects:
- * DynBuf is updated with serialized form of the updates.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityBuildUpdates(void *param, // IN
- int flags) // IN
-{
- Bool retVal = TRUE;
- UnityUpdateChannel *updateChannel = reinterpret_cast<UnityUpdateChannel*>(param);
-
- ASSERT(updateChannel);
-
- DynBuf_SetSize(&updateChannel->updates, updateChannel->cmdSize);
- Unity_GetUpdates(flags);
- /*
- * Write the final '\0' to the DynBuf to signal that we're all out of
- * updates.
- */
- DynBuf_AppendString(&updateChannel->updates, "");
-
- /*
- * If there are no updates, Unity_GetUpdates appended an empty string, i.e. null.
- */
-
- if (DynBuf_GetSize(&updateChannel->updates) > updateChannel->cmdSize + 1) {
- if (!UnitySendUpdates(updateChannel)) {
- retVal = FALSE;
- }
- }
- return retVal;
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityShouldShowTaskbar --
- *
- * Sends an RPC to retrieve whether the guest should show the taskbar and
- * returns the value.
- *
- * Results:
- * TRUE if the taskbar should be visible.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityShouldShowTaskbar()
-{
- char *reply = NULL;
- size_t replyLen;
- Bool showTaskbar = FALSE;
-
- if (!RpcOut_sendOne(&reply, &replyLen, UNITY_RPC_VMX_SHOW_TASKBAR)) {
- Debug("%s: could not get the VMX show taskbar setting, assuming FALSE\n",
- __FUNCTION__);
- showTaskbar = FALSE;
- } else {
- uint32 value = 0;
-
- if (StrUtil_StrToUint(&value, reply)) {
- showTaskbar = (value == 0) ? FALSE : TRUE;
- } else {
- showTaskbar = FALSE;
- }
- }
- return showTaskbar;
-}
-
-} /* namespace tools */ } /* namespace vmware */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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 unityTclo.h
- *
- * Functions for handling/dispatching Unity TCLO RPCs.
- */
-
-#include "vmware/tools/plugin.h"
-#include "unityPlugin.h"
-
-extern "C" {
- #include "rpcin.h"
-};
-
-namespace vmware { namespace tools {
-
-void UnityTcloInit(gpointer serviceObj);
-void UnityTcloCleanup();
-
-UnityUpdateChannel *UnityUpdateChannelInit(void);
-void UnityUpdateChannelCleanup(UnityUpdateChannel *updateChannel);
-Bool UnitySendUpdates(void *param);
-void UnityUpdateCallbackFn(void *param, UnityUpdate *update);
-Bool UnityBuildUpdates(void *param, int flags);
-
-Bool UnitySendWindowContents(UnityWindowId windowID,
- uint32 imageWidth,
- uint32 imageHeight,
- const char *imageData,
- uint32 imageLength);
-Bool UnitySendRequestMinimizeOperation(UnityWindowId windowId,
- uint32 sequence);
-Bool UnityShouldShowTaskbar();
-
-gboolean UnityTcloEnter(RpcInData *data);
-gboolean UnityTcloGetUpdate(RpcInData *data);
-gboolean UnityTcloExit(RpcInData *data);
-gboolean UnityTcloGetWindowPath(RpcInData *data);
-gboolean UnityTcloWindowCommand(RpcInData *data);
-gboolean UnityTcloGetWindowContents(RpcInData *data);
-gboolean UnityTcloGetIconData(RpcInData *data);
-gboolean UnityTcloSetDesktopWorkArea(RpcInData *data);
-gboolean UnityTcloSetTopWindowGroup(RpcInData *data);
-gboolean UnityTcloShowTaskbar(RpcInData *data);
-gboolean UnityTcloMoveResizeWindow(RpcInData *data);
-gboolean UnityTcloSetDesktopConfig(RpcInData *data);
-gboolean UnityTcloSetDesktopActive(RpcInData *data);
-gboolean UnityTcloSetWindowDesktop(RpcInData *data);
-gboolean UnityTcloConfirmOperation(RpcInData *data);
-gboolean UnityTcloSetUnityOptions(RpcInData *data);
-gboolean UnityTcloRequestWindowContents(RpcInData *data);
-gboolean UnityTcloSendMouseWheel(RpcInData *data);
-
-} /* namespace tools */ } /* namespace vmware */
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * unityWindowTracker.h --
- *
- * Used to buffer state about a window manager.
- */
-
-#include <stdio.h>
-#include "vmware.h"
-#include "str.h"
-#include "strutil.h"
-#include "util.h"
-#include "log.h"
-#include "unityWindowTracker.h"
-
-#define LOGLEVEL_MODULE uwt
-#include "loglevel_user.h"
-
-/*
- * Helper Functions --
- */
-
-static void FreeWindowInfo(UnityWindowInfo *info);
-static int RemoveUntouchedWindow(const char *key, void *value,
- void *clientData);
-static int GarbageCollectRemovedWindows(const char *key, void *value,
- void *clientData);
-static int ResetChangedBits(const char *key, void *value, void *clientData);
-static int PushUpdates(const char *key, void *value, void *clientData);
-static int PushRemoveWindow(const char *key, void *value, void *clientData);
-static Bool TitlesEqual(DynBuf *first, DynBuf *second);
-static int PushZOrder(UnityWindowTracker *tracker);
-static int PushActiveDesktop(UnityWindowTracker *tracker);
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_Init --
- *
- * Create a new unity window tracker. The client should pass in a
- * callbacks object, which will be used to notify them of updates
- * in UnityWindowTracker_RequestUpdates.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_Init(UnityWindowTracker *tracker, // IN
- UnityUpdateCallback cb) // IN
-{
- memset(tracker, 0, sizeof(UnityWindowTracker));
- tracker->cb = cb;
- tracker->windows = HashTable_Alloc(128, HASH_INT_KEY,
- (HashTableFreeEntryFn)FreeWindowInfo);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_Cleanup --
- *
- * Destory a unity window tracker.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_Cleanup(UnityWindowTracker *tracker) // IN
-{
- if (NULL != tracker->windows) {
- HashTable_Free(tracker->windows);
- }
- memset(tracker, 0, sizeof(UnityWindowTracker));
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityWindowTracker_SetDataFreeFunc --
- *
- * Sets the function that will be called to free the app data associated with a
- * window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_SetDataFreeFunc(UnityWindowTracker *tracker, // IN
- UnityDataFreeFunc freeFn) // IN
-{
- tracker->freeFn = freeFn;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_LookupWindow --
- *
- * Returns the window with the specified window id, or NULL if no
- * such window exists.
- *
- * Results:
- * See above.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-UnityWindowInfo *
-UnityWindowTracker_LookupWindow(UnityWindowTracker *tracker, // IN
- UnityWindowId id) // IN
-{
- UnityWindowInfo *info = NULL;
- HashTable_Lookup(tracker->windows, (const char *)(long)id, (void **)&info);
- return info;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_AddWindow --
- *
- * Add a new window to the window tracker
- *
- * Results:
- * A pointer to the UnityWindowInfo for the added window
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-UnityWindowInfo *
-UnityWindowTracker_AddWindow(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- DynBuf *windowPathUtf8, // IN
- DynBuf *execPathUtf8) // IN
-{
- UnityWindowInfo *info = UnityWindowTracker_LookupWindow(tracker, id);
- if (!info) {
- size_t windowPathSize;
- size_t execPathSize;
-
- info = (UnityWindowInfo *)Util_SafeCalloc(1, sizeof(UnityWindowInfo));
- info->tracker = tracker;
- info->id = id;
- info->type = UNITY_WINDOW_TYPE_NONE;
- info->desktopId = tracker->activeDesktopId;
- DynBuf_Init(&info->titleUtf8);
- DynBuf_Init(&info->windowPathUtf8);
- DynBuf_Init(&info->execPathUtf8);
-
- /*
- * Ensure that the provided paths only include one NUL terminator
- * at the end of the buffer, or keep the paths empty otherwise.
- */
- windowPathSize = DynBuf_GetSize(windowPathUtf8);
- if (windowPathSize > 0) {
- Bool isNullTerminated = Str_Strlen((char *)DynBuf_Get(windowPathUtf8),
- windowPathSize) == windowPathSize - 1;
- ASSERT(isNullTerminated);
- if (isNullTerminated) {
- DynBuf_Copy(windowPathUtf8, &info->windowPathUtf8);
- }
- }
- execPathSize = DynBuf_GetSize(execPathUtf8);
- if (execPathSize > 0) {
- Bool isNullTerminated = Str_Strlen((char *)DynBuf_Get(execPathUtf8),
- execPathSize) == execPathSize - 1;
- ASSERT(isNullTerminated);
- if (isNullTerminated) {
- DynBuf_Copy(execPathUtf8, &info->execPathUtf8);
- }
- }
-
- LOG(2, ("Unity adding new window (id:%d)\n", id));
- HashTable_Insert(tracker->windows, (const char *)(long)id, info);
- info->changed |= UNITY_CHANGED_ADDED;
- info->changed |= UNITY_CHANGED_WINDOW_DESKTOP;
- } else {
- info->changed &= ~UNITY_CHANGED_REMOVED;
- LOG(2, ("Window already exists in UnityAddWindow (id:%d)\n", id));
- }
- info->touched = TRUE;
-
- return info;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_AddWindowWithData --
- *
- * Add a new window to the window tracker, and sets its application data to the
- * specified 'data'. The tracker's DataFreeFunc will be used to free 'data' when it
- * needs to be destroyed (see UnityWindowTracker_SetDataFreeFunc). If the window
- * already exists and has 'data' set on it, that will be destroyed and replaced with
- * the new 'data' pointer.
- *
- * Results:
- * A pointer to the UnityWindowInfo for the added window.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-UnityWindowInfo *
-UnityWindowTracker_AddWindowWithData(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- DynBuf *windowPathUtf8, // IN
- DynBuf *execPathUtf8, // IN
- void *data) // IN
-{
- UnityWindowInfo *info = UnityWindowTracker_AddWindow(tracker,
- id,
- windowPathUtf8,
- execPathUtf8);
-
- if (info) {
- if (info->data
- && tracker->freeFn
- && (info->data != data)) {
- tracker->freeFn(tracker, info, info->data);
- }
-
- info->data = data;
- }
-
- return info;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_MoveWindow --
- *
- * Notify the window tracker that the window with the specified id
- * has moved.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_MoveWindow(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- int x1, // IN
- int y1, // IN
- int x2, // IN
- int y2) // IN
-{
- UnityWindowInfo *info = UnityWindowTracker_LookupWindow(tracker, id);
- if (info) {
- info->touched = TRUE;
- if (info->rect.x1 != x1 || info->rect.y1 != y1
- || x2 != info->rect.x2 || y2 != info->rect.y2) {
- LOG(2, ("Unity moving window (id:%d pos:%d,%d, %d,%d)\n", id, x1, y1, x2, y2));
- info->rect.x1 = x1;
- info->rect.y1 = y1;
- info->rect.x2 = x2;
- info->rect.y2 = y2;
- info->changed |= UNITY_CHANGED_POSITION;
- }
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_SetWindowTitle --
- *
- * Notify the window tracker that the window with the specified id
- * has changed its title.
- *
- * This function does not take ownership of the DynBuf; caller
- * is assumed to free it.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_SetWindowTitle(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- DynBuf *titleUtf8) // IN
-{
- UnityWindowInfo *info = UnityWindowTracker_LookupWindow(tracker, id);
- if (info) {
- info->touched = TRUE;
- if (!TitlesEqual(&info->titleUtf8, titleUtf8)) {
- LOG(2, ("Unity setting window title (id:%d title:%s)\n", id,
- (const unsigned char*)DynBuf_Get(titleUtf8)));
- info->changed |= UNITY_CHANGED_TITLE;
- DynBuf_Destroy(&info->titleUtf8);
- DynBuf_Copy(titleUtf8, &info->titleUtf8);
- }
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_ChangeWindowRegion --
- *
- * Change the window region of the specified window. A NULL region
- * means the window region is simply the bounds of the window.
- *
- * This function does not take ownership of the RegionPtr; caller is
- * assumed to free it.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_ChangeWindowRegion(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- RegionPtr region) // IN
-{
- UnityWindowInfo *info = UnityWindowTracker_LookupWindow(tracker, id);
- if (info) {
- info->touched = TRUE;
- if (region) {
- if (!info->region) {
- LOG(2, ("Unity adding window region (id:%d)\n", id));
- info->changed |= UNITY_CHANGED_REGION;
- info->region = miRegionCreate(&miEmptyBox, 0);
- }
- if (!miRegionsEqual(info->region, region)) {
- LOG(2, ("Unity changing window region (id:%d)\n", id));
- info->changed |= UNITY_CHANGED_REGION;
- miRegionCopy(info->region, region);
- }
- } else {
- if (info->region) {
- LOG(2, ("Unity removing window region (id:%d)\n", id));
- info->changed |= UNITY_CHANGED_REGION;
- miRegionDestroy(info->region);
- info->region = NULL;
- }
- }
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_ChangeWindowState --
- *
- * Change window state (minimized or not) of the specified window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_ChangeWindowState(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- uint32 state) // IN
-{
- UnityWindowInfo *info = UnityWindowTracker_LookupWindow(tracker, id);
- if (info) {
- info->touched = TRUE;
- if (state != info->state) {
- info->changed |= UNITY_CHANGED_WINDOW_STATE;
- info->state = state;
- LOG(2, ("Unity changing window state (id:%d) to %d\n", id, state));
- }
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_GetWindowState --
- *
- * Get window state (minimized or not) of the specified window.
- *
- * Results:
- * TRUE if the window exists in the window tracker.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityWindowTracker_GetWindowState(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- uint32 *state) // IN
-{
- UnityWindowInfo *info = UnityWindowTracker_LookupWindow(tracker, id);
- ASSERT(state);
- if (info) {
- *state = info->state;
- return TRUE;
- }
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityWindowTracker_ChangeWindowAttribute --
- *
- * Sets the value of a particular attribute on a particular window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Marks the window tracker as having updates.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_ChangeWindowAttribute(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- UnityWindowAttribute attr, // IN
- Bool enabled) // IN
-{
- UnityWindowInfo *info;
- ASSERT(tracker);
- ASSERT(attr < UNITY_MAX_ATTRIBUTES);
-
- info = UnityWindowTracker_LookupWindow(tracker, id);
- if (info) {
- info->touched = TRUE;
-
- /*
- * If this is a new attribute (that didn't exist before) or
- * if the attribute value has changed, remember the new value
- * (enabled or disabled) and mark it as existing and
- * changed.
- */
-
- if (!(info->attributes[attr] & UNITY_INFO_ATTR_EXISTS) ||
- ((info->attributes[attr] & UNITY_INFO_ATTR_ENABLED) !=
- (enabled ? UNITY_INFO_ATTR_ENABLED : 0))) {
- info->changed |= UNITY_CHANGED_WINDOW_ATTRIBUTES;
- info->attributes[attr] = (UNITY_INFO_ATTR_EXISTS |
- UNITY_INFO_ATTR_CHANGED |
- (enabled ? UNITY_INFO_ATTR_ENABLED : 0));
- LOG(2, ("Unity changing window (id:%d) attribute %d = %s\n",
- id, attr, enabled ? "TRUE" : "FALSE"));
- }
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityWindowTracker_GetWindowAttribute --
- *
- * Retrieves the current value of a window attribute.
- *
- * Results:
- * TRUE if the attribute value was retrieved successfully.
- * FALSE if the attribute had never been set on the specified window, or if the
- * window does not exist.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-UnityWindowTracker_GetWindowAttribute(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- UnityWindowAttribute attr, // IN
- Bool *enabled) // IN
-{
- Bool retval = FALSE;
- UnityWindowInfo *info;
- ASSERT(tracker);
- ASSERT(attr < UNITY_MAX_ATTRIBUTES);
-
- info = UnityWindowTracker_LookupWindow(tracker, id);
- if (info
- && (info->attributes[attr] & UNITY_INFO_ATTR_EXISTS)) {
- *enabled = (info->attributes[attr] & UNITY_INFO_ATTR_ENABLED) ? TRUE : FALSE;
- retval = TRUE;
- }
-
- return retval;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityWindowTracker_ChangeWindowType --
- *
- * Sets the window type of the specified window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Marks the window tracker as having updates.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_ChangeWindowType(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- UnityWindowType winType) // IN
-{
- UnityWindowInfo *info;
- ASSERT(tracker);
-
- info = UnityWindowTracker_LookupWindow(tracker, id);
- if (info) {
- info->touched = TRUE;
- if (winType != info->type) {
- info->changed |= UNITY_CHANGED_WINDOW_TYPE;
- info->type = winType;
- LOG(2, ("Unity changing window (id:%d) type to %d\n",
- id, winType));
- }
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityWindowTracker_GetWindowType --
- *
- * Retrieves the window type of the specified window.
- *
- * Results:
- * TRUE if successful, FALSE if failed.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-UnityWindowTracker_GetWindowType(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- UnityWindowType *winType) // IN
-{
- Bool retval = FALSE;
- UnityWindowInfo *info;
-
- ASSERT(tracker);
- ASSERT(winType);
-
- info = UnityWindowTracker_LookupWindow(tracker, id);
- if (info) {
- *winType = info->type;
- retval = TRUE;
- }
-
- return retval;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityWindowTracker_NotifyIconChanged --
- *
- * Marks the window tracker as having a changed icon for a window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_NotifyIconChanged(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- UnityIconType iconType) // IN
-{
- UnityWindowInfo *info;
-
- ASSERT(tracker);
- ASSERT(iconType < UNITY_MAX_ICONS);
-
- info = UnityWindowTracker_LookupWindow(tracker, id);
- if (info) {
- LOG(2, ("Unity icon changed on window (id:%d)\n", id));
- info->touched = TRUE;
- info->changed |= UNITY_CHANGED_WINDOW_ICONS;
- info->icons[iconType] |= UNITY_INFO_ATTR_CHANGED | UNITY_INFO_ATTR_EXISTS;
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityWindowTracker_ChangeWindowDesktop --
- *
- * Saves the window desktop information if that was changed.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Window desktop information might be updated.
- * Window marked as touched.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_ChangeWindowDesktop(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- UnityDesktopId desktopId) // IN
-{
- UnityWindowInfo *info;
- ASSERT(tracker);
-
- info = UnityWindowTracker_LookupWindow(tracker, id);
- if (info) {
- info->touched = TRUE;
- if (desktopId != info->desktopId) {
- info->changed |= UNITY_CHANGED_WINDOW_DESKTOP;
- info->desktopId = desktopId;
- LOG(2, ("Unity changing window (id:%u) desktop to %d\n",
- id, desktopId));
- }
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityWindowTracker_GetWindowDesktop --
- *
- * Get the window desktop information.
- *
- * Results:
- * TRUE if this window exists in the window tracker, desktopId contains
- * window desktop.
- * FALSE otherwise, desktopId undefined.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-UnityWindowTracker_GetWindowDesktop(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- UnityDesktopId *desktopId) // OUT
-{
- Bool retval = FALSE;
- UnityWindowInfo *info;
-
- ASSERT(tracker);
- ASSERT(desktopId);
-
- info = UnityWindowTracker_LookupWindow(tracker, id);
- if (info) {
- *desktopId = info->desktopId;
- retval = TRUE;
- }
-
- return retval;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityWindowTracker_ChangeActiveDesktop --
- *
- * Saves the active desktop information if that was changed.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Active desktop information might be updated.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_ChangeActiveDesktop(UnityWindowTracker *tracker, // IN
- UnityDesktopId desktopId) // IN
-{
- if (desktopId != tracker->activeDesktopId) {
- tracker->activeDesktopId = desktopId;
- tracker->activeDesktopChanged = TRUE;
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityWindowTracker_GetActiveDesktop --
- *
- * Return the active desktop id.
- *
- * Results:
- * Active desktop id.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-UnityDesktopId
-UnityWindowTracker_GetActiveDesktop(UnityWindowTracker *tracker) // IN
-{
- return tracker->activeDesktopId;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_RemoveWindow --
- *
- * Remove the window with the specified id from the tracker.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_RemoveWindow(UnityWindowTracker *tracker, // IN
- UnityWindowId id) // IN
-{
- UnityWindowInfo *info = UnityWindowTracker_LookupWindow(tracker, id);
- if (info) {
- LOG(2, ("Unity removing window (id:%d)\n", id));
- info->changed |= UNITY_CHANGED_REMOVED;
- info->touched = TRUE;
- /*
- * Don't remove it yet. We can only do so later...
- */
- }
-}
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityWindowTracker_RemoveAllWindows --
- *
- * Removes all the windows from the window tracker, *without* notifying
- * the client. This function is meant to be used to "reset" the tracker
- * state after we have exited Unity.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-
-void
-UnityWindowTracker_RemoveAllWindows(UnityWindowTracker *tracker)
-{
- HashTable_Clear(tracker->windows);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_SendUpdate --
- *
- * Update the window tracker via a UnityUpdate structure instead
- * of a call to AddWindow, MoveWindow, etc. Useful for forwarding
- * notifications between unity windows trackers without writing
- * a ton of boilerplate.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_SendUpdate(UnityWindowTracker *tracker, // IN
- UnityUpdate *update) // IN
-{
- switch (update->type) {
- case UNITY_UPDATE_ADD_WINDOW:
- UnityWindowTracker_AddWindow(tracker,
- update->u.addWindow.id,
- &update->u.addWindow.windowPathUtf8,
- &update->u.addWindow.execPathUtf8);
- break;
-
- case UNITY_UPDATE_MOVE_WINDOW:
- UnityWindowTracker_MoveWindow(tracker,
- update->u.moveWindow.id,
- update->u.moveWindow.rect.x1,
- update->u.moveWindow.rect.y1,
- update->u.moveWindow.rect.x2,
- update->u.moveWindow.rect.y2);
- break;
-
- case UNITY_UPDATE_REMOVE_WINDOW:
- UnityWindowTracker_RemoveWindow(tracker,
- update->u.removeWindow.id);
- break;
-
- case UNITY_UPDATE_CHANGE_WINDOW_REGION:
- UnityWindowTracker_ChangeWindowRegion(tracker,
- update->u.changeWindowRegion.id,
- update->u.changeWindowRegion.region);
- break;
-
- case UNITY_UPDATE_CHANGE_WINDOW_TITLE:
- UnityWindowTracker_SetWindowTitle(tracker,
- update->u.changeWindowTitle.id,
- &update->u.changeWindowTitle.titleUtf8);
- break;
-
- case UNITY_UPDATE_CHANGE_ZORDER:
- UnityWindowTracker_SetZOrder(tracker, update->u.zorder.ids,
- update->u.zorder.count);
- /*
- * This function is only every called from the host. Thus, if we get
- * a zorder changed event from the guest it's safe to blindly trust it
- * mark the zorder as changed. See bug 409742 for more info.
- */
- tracker->zorderChanged = TRUE;
- break;
-
- case UNITY_UPDATE_CHANGE_WINDOW_STATE:
- UnityWindowTracker_ChangeWindowState(tracker,
- update->u.changeWindowState.id,
- update->u.changeWindowState.state);
- break;
-
- case UNITY_UPDATE_CHANGE_WINDOW_ATTRIBUTE:
- UnityWindowTracker_ChangeWindowAttribute(tracker,
- update->u.changeWindowAttribute.id,
- update->u.changeWindowAttribute.attr,
- update->u.changeWindowAttribute.value);
- break;
-
- case UNITY_UPDATE_CHANGE_WINDOW_TYPE:
- UnityWindowTracker_ChangeWindowType(tracker,
- update->u.changeWindowType.id,
- update->u.changeWindowType.winType);
- break;
-
- case UNITY_UPDATE_CHANGE_WINDOW_ICON:
- UnityWindowTracker_NotifyIconChanged(tracker,
- update->u.changeWindowIcon.id,
- update->u.changeWindowIcon.iconType);
- break;
- case UNITY_UPDATE_CHANGE_WINDOW_DESKTOP:
- UnityWindowTracker_ChangeWindowDesktop(tracker,
- update->u.changeWindowDesktop.id,
- update->u.changeWindowDesktop.desktopId);
- break;
-
- case UNITY_UPDATE_CHANGE_ACTIVE_DESKTOP:
- UnityWindowTracker_ChangeActiveDesktop(tracker,
- update->u.changeActiveDesktop.desktopId);
- break;
-
- default:
- NOT_IMPLEMENTED();
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_SetZOrder --
- *
- * Notify the window tracker of the Z-order of all windows. Window ids
- * at the front of the list are at the top of the z-order.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_SetZOrder(UnityWindowTracker *tracker, // IN
- UnityWindowId zorder[], // IN
- int count) // IN
-{
- count = MIN(count, ARRAYSIZE(tracker->zorder));
-
- if ((count != tracker->count) ||
- (memcmp(tracker->zorder, zorder, count * sizeof(tracker->zorder[0])) != 0)) {
- memcpy(tracker->zorder, zorder, count * sizeof(tracker->zorder[0]));
- tracker->count = count;
- tracker->zorderChanged = TRUE;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_SetZPosition --
- *
- * Notify the window tracker of the Z-order of one window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Updates the Z-ordering of the tracker.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_SetZPosition(UnityWindowTracker *tracker, // IN
- UnityWindowId id, // IN
- uint32 zorder) // IN
-{
- int newIndex, oldIndex;
-
- /* First, figure out where the window will be in the list */
- switch(zorder) {
- case UNITY_WINDOW_ORDER_BOTTOM:
- newIndex = tracker->count - 1;
- break;
- case UNITY_WINDOW_ORDER_TOP:
- default:
- newIndex = zorder;
- break;
- }
-
- /* Then, find where the window is the list. If it's not there, it's an error. */
- for (oldIndex = 0; oldIndex < tracker->count; oldIndex++) {
- if (id == tracker->zorder[oldIndex]) {
- break;
- }
- }
- ASSERT(oldIndex < tracker->count);
-
- /* Next, make space for the WindowId at its new spot */
- if (newIndex < oldIndex) {
- memmove(tracker->zorder + newIndex + 1, tracker->zorder + newIndex,
- oldIndex - newIndex);
- } else if (newIndex > oldIndex) {
- memmove(tracker->zorder + oldIndex, tracker->zorder + oldIndex + 1,
- newIndex - oldIndex);
- }
-
- /* Finally, put it in place */
- tracker->zorder[newIndex] = id;
- tracker->zorderChanged = TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityWindowTracker_RequestUpdates --
- *
- * Request a summary of all the updates pushed into the window tracker
- * since the last call to UnityWindowTracker_RequestUpdates.
- *
- * If UNITY_UPDATE_INCREMENTAL is set in flags, callbacks will only
- * fire for elements which have changed since the last call to
- * UnityWindowTracker_RequestUpdates. Otherwise the entire state of
- * the window tracker is sent via the callbacks.
- *
- * If UNITY_UPDATE_REMOVE_UNTOUCHED is set in flags, windows for
- * which there have been no updates since the last
- * UnityWindowTracker_RequestUpdates call will be automatically removed.
- * Useful if the client has no way of getting remove window notifications.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Lots of callbacks are fired.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_RequestUpdates(UnityWindowTracker *tracker, // IN
- uint32 flags, // IN
- void *param) // IN
-{
- tracker->cbparam = param;
- tracker->updateFlags = flags;
-
- /*
- * If necessary, remove windows which didn't receive updates.
- */
- if (flags & UNITY_UPDATE_REMOVE_UNTOUCHED) {
- HashTable_ForEach(tracker->windows, RemoveUntouchedWindow, tracker);
- }
-
- /*
- * Push updates for the windows remaining...
- * We push removed windows last to prevent temporary periods where a guest
- * app has no windows.
- */
- HashTable_ForEach(tracker->windows, PushUpdates, tracker);
- HashTable_ForEach(tracker->windows, PushRemoveWindow, tracker);
-
- /* Push Z order */
- PushZOrder(tracker);
-
- /* Push active desktop info */
- PushActiveDesktop(tracker);
-
- /*
- * ...then really delete things which were removed...
- */
- while (HashTable_ForEach(tracker->windows, GarbageCollectRemovedWindows,
- tracker)) {
- continue;
- }
-
- /*
- * ...and clear all the changed and touched bits of what's left to get ready
- * for the next iteration.
- */
- HashTable_ForEach(tracker->windows, ResetChangedBits, NULL);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * FreeWindowInfo --
- *
- * Destroy a window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-FreeWindowInfo(UnityWindowInfo *info) // IN
-{
- if (info) {
- UnityWindowTracker *tracker = info->tracker;
-
- if (tracker->freeFn && info->data) {
- tracker->freeFn(tracker, info, info->data);
- }
-
- if (info->region) {
- miRegionDestroy(info->region);
- }
- DynBuf_Destroy(&info->titleUtf8);
- DynBuf_Destroy(&info->windowPathUtf8);
- DynBuf_Destroy(&info->execPathUtf8);
- free(info);
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * RemoveUntouchedWindow --
- *
- * If the window specified hasn't been touched (i.e. an update function
- * has been called on it), remove it from the window tracker.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-RemoveUntouchedWindow(const char *key, // IN: window id
- void *value, // IN: UnityWindowInfo
- void *clientData) // IN: UnityWindowTracker
-{
- UnityWindowTracker *tracker = (UnityWindowTracker *)clientData;
- UnityWindowInfo *info = (UnityWindowInfo *)value;
- if (!info->touched) {
- UnityWindowId id = (UnityWindowId)(long)key;
- LOG(2, ("Removing untouched window (id:%d)\n", id));
- UnityWindowTracker_RemoveWindow(tracker, id);
- }
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * GarbageCollectRemovedWindows --
- *
- * Delete all window objects for windows which are marked as
- * removed.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-GarbageCollectRemovedWindows(const char *key, // IN: window id
- void *value, // IN: UnityWindowInfo
- void *clientData) // IN: UnityWindowTracker
-{
- UnityWindowTracker *tracker = (UnityWindowTracker *)clientData;
- UnityWindowInfo *info = (UnityWindowInfo *)value;
- if (info->reap) {
- LOG(2, ("Destroying window (id:%d)\n", (UnityWindowId)(long)key));
- HashTable_Delete(tracker->windows, key);
- return 1;
- }
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * ResetChangedBits --
- *
- * Reset the changed and touched bits for this window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-ResetChangedBits(const char *key, // IN: window id
- void *value, // IN: UnityWindowInfo
- void *clientData) // IN: UnityWindowTracker
-{
- UnityWindowInfo *info = (UnityWindowInfo *)value;
- int i;
-
- if (info->changed & UNITY_CHANGED_WINDOW_ATTRIBUTES) {
- for (i = 0; i < UNITY_MAX_ATTRIBUTES; i++) {
- info->attributes[i] &= ~UNITY_INFO_ATTR_CHANGED;
- }
- }
-
- if (info->changed & UNITY_CHANGED_WINDOW_ICONS) {
- for (i = 0; i < UNITY_MAX_ICONS; i++) {
- info->icons[i] &= ~UNITY_INFO_ATTR_CHANGED;
- }
- }
-
- info->changed = 0;
- info->touched = FALSE;
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * PushRemoveWindow --
- *
- * Sends a remove window update for this window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-PushRemoveWindow(const char *key, // IN: window id
- void *value, // IN: UnityWindowInfo
- void *clientData) // IN: UnityWindowTracker
-{
- UnityWindowInfo *info = (UnityWindowInfo *)value;
-
- if (info->changed & UNITY_CHANGED_REMOVED) {
- UnityWindowTracker *tracker = (UnityWindowTracker *)clientData;
- UnityWindowId id = (UnityWindowId)(long)key;
- UnityUpdate update;
-
- /*
- * Now that we've sent the update, mark the window as deleted
- * so it will be reaped.
- */
- info->reap = TRUE;
- update.type = UNITY_UPDATE_REMOVE_WINDOW;
- update.u.removeWindow.id = id;
- (*tracker->cb)(tracker->cbparam, &update);
- }
-
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * PushUpdates --
- *
- * Fire all callback functions relevant for this window (as determined
- * by the changed bits).
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-PushUpdates(const char *key, // IN: window id
- void *value, // IN: UnityWindowInfo
- void *clientData) // IN: UnityWindowTracker
-{
- UnityWindowTracker *tracker = (UnityWindowTracker *)clientData;
- UnityWindowInfo *info = (UnityWindowInfo *)value;
- UnityWindowId id = (UnityWindowId)(long)key;
- UnityUpdate update;
- Bool incremental = (tracker->updateFlags & UNITY_UPDATE_INCREMENTAL) != 0;
-
- if (info->changed & UNITY_CHANGED_REMOVED) {
- // This is handled in PushRemoveWindow.
- return 0;
- }
-
- if (!incremental || (info->changed & UNITY_CHANGED_ADDED)) {
- update.type = UNITY_UPDATE_ADD_WINDOW;
- update.u.addWindow.id = id;
- DynBuf_Init(&update.u.addWindow.windowPathUtf8);
- DynBuf_Init(&update.u.addWindow.execPathUtf8);
- if (DynBuf_GetSize(&info->windowPathUtf8)) {
- DynBuf_Copy(&info->windowPathUtf8, &update.u.addWindow.windowPathUtf8);
- }
- if (DynBuf_GetSize(&info->execPathUtf8)) {
- DynBuf_Copy(&info->execPathUtf8, &update.u.addWindow.execPathUtf8);
- }
- (*tracker->cb)(tracker->cbparam, &update);
- DynBuf_Destroy(&update.u.addWindow.windowPathUtf8);
- DynBuf_Destroy(&update.u.addWindow.execPathUtf8);
- }
- if (!incremental || (info->changed & UNITY_CHANGED_POSITION)) {
- update.type = UNITY_UPDATE_MOVE_WINDOW;
- update.u.moveWindow.id = id;
- update.u.moveWindow.rect = info->rect;
- (*tracker->cb)(tracker->cbparam, &update);
- }
- if (!incremental || (info->changed & UNITY_CHANGED_REGION)) {
- update.type = UNITY_UPDATE_CHANGE_WINDOW_REGION;
- update.u.changeWindowRegion.id = id;
- update.u.changeWindowRegion.region = info->region;
- (*tracker->cb)(tracker->cbparam, &update);
- }
- if (!incremental || (info->changed & UNITY_CHANGED_TITLE)) {
- update.type = UNITY_UPDATE_CHANGE_WINDOW_TITLE;
- update.u.changeWindowTitle.id = id;
- DynBuf_Init(&update.u.changeWindowTitle.titleUtf8);
- DynBuf_Copy(&info->titleUtf8, &update.u.changeWindowTitle.titleUtf8);
- (*tracker->cb)(tracker->cbparam, &update);
- DynBuf_Destroy(&update.u.changeWindowTitle.titleUtf8);
- }
- if (!incremental || (info->changed & UNITY_CHANGED_WINDOW_ICONS)) {
- UnityIconType i;
-
- update.type = UNITY_UPDATE_CHANGE_WINDOW_ICON;
- update.u.changeWindowIcon.id = id;
- for (i = 0; i < UNITY_MAX_ICONS; i++) {
- if ((info->icons[i] & UNITY_INFO_ATTR_EXISTS)
- && (!incremental
- || (info->icons[i] & UNITY_INFO_ATTR_CHANGED))) {
- update.u.changeWindowIcon.iconType = i;
- (*tracker->cb)(tracker->cbparam, &update);
- }
- }
- }
- if (!incremental || (info->changed & UNITY_CHANGED_WINDOW_TYPE)) {
- update.type = UNITY_UPDATE_CHANGE_WINDOW_TYPE;
- update.u.changeWindowType.id = id;
- update.u.changeWindowType.winType = info->type;
- (*tracker->cb)(tracker->cbparam, &update);
- }
-
- /*
- * Please make sure WINDOW_ATTRIBUTES is checked before WINDOW_STATE, to allow
- * vmware-vmx on the host side to only pay attention to WINDOW_ATTRIBUTES if
- * desired.
- */
- if (!incremental || (info->changed & UNITY_CHANGED_WINDOW_ATTRIBUTES)) {
- UnityWindowAttribute i;
-
- update.type = UNITY_UPDATE_CHANGE_WINDOW_ATTRIBUTE;
- update.u.changeWindowAttribute.id = id;
- for (i = 0; i < UNITY_MAX_ATTRIBUTES; i++) {
- if ((info->attributes[i] & UNITY_INFO_ATTR_EXISTS)
- && (!incremental ||
- (info->attributes[i] & UNITY_INFO_ATTR_CHANGED))) {
- update.u.changeWindowAttribute.attr = i;
- update.u.changeWindowAttribute.value =
- (info->attributes[i] & UNITY_INFO_ATTR_ENABLED) ? TRUE : FALSE;
- (*tracker->cb)(tracker->cbparam, &update);
- }
- }
- }
-
- if (!incremental || (info->changed & UNITY_CHANGED_WINDOW_STATE)) {
- update.type = UNITY_UPDATE_CHANGE_WINDOW_STATE;
- update.u.changeWindowState.id = id;
- update.u.changeWindowState.state = info->state;
- (*tracker->cb)(tracker->cbparam, &update);
- }
-
- if (!incremental || (info->changed & UNITY_CHANGED_WINDOW_DESKTOP)) {
- update.type = UNITY_UPDATE_CHANGE_WINDOW_DESKTOP;
- update.u.changeWindowDesktop.id = id;
- update.u.changeWindowDesktop.desktopId = info->desktopId;
- (*tracker->cb)(tracker->cbparam, &update);
- }
-
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * PushZOrder --
- *
- * Fire callback function if Z Order was changed
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-PushZOrder(UnityWindowTracker *tracker) // IN: UnityWindowTracker
-{
- UnityUpdate update;
- Bool incremental = (tracker->updateFlags & UNITY_UPDATE_INCREMENTAL) != 0;
- if (!incremental || tracker->zorderChanged) {
- update.type = UNITY_UPDATE_CHANGE_ZORDER;
- update.u.zorder.count = tracker->count;
- memcpy(&update.u.zorder.ids, tracker->zorder,
- tracker->count * sizeof(update.u.zorder.ids[0]));
- (*tracker->cb)(tracker->cbparam, &update);
-
- tracker->zorderChanged = FALSE;
- }
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * PushActiveDesktop --
- *
- * Fire callback function if the active desktop was changed.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-PushActiveDesktop(UnityWindowTracker *tracker) // IN: UnityWindowTracker
-{
- UnityUpdate update;
- Bool incremental = (tracker->updateFlags & UNITY_UPDATE_INCREMENTAL) != 0;
- if (!incremental || tracker->activeDesktopChanged) {
- update.type = UNITY_UPDATE_CHANGE_ACTIVE_DESKTOP;
- update.u.changeActiveDesktop.desktopId = tracker->activeDesktopId;
- (*tracker->cb)(tracker->cbparam, &update);
-
- tracker->activeDesktopChanged = FALSE;
- }
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * TitlesEqual--
- *
- * Performs string comparison on the titles held in DynBufs
- *
- * Results:
- * TRUE if first == second
- * FALSE if first != second
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-TitlesEqual(DynBuf *first, // IN: First window title
- DynBuf *second) // IN: Second window title
-{
- if (DynBuf_GetSize(first) != DynBuf_GetSize(second)) {
- return FALSE;
- }
- return (strncmp((const unsigned char*)DynBuf_Get(first),
- (const unsigned char*)DynBuf_Get(second),
- DynBuf_GetSize(first)) == 0) ? TRUE : FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityWindowTracker_ParseUnityUpdate --
- *
- * Validate and parse Unity update command strings. The caller
- * should pass in a UnityUpdateCallback function (see lib/public/
- * unityWindowTracker.h). The callback will fire once for each
- * window update in the result string.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityWindowTracker_ParseUnityUpdate(const char *result, // IN
- int len, // IN
- UnityUpdateCallback cb, // IN
- void *param) // IN
-{
- if (result && len > 1) {
- uint32 id = 0;
- int x1, y1, x2, y2;
- const char *buf;
-
- /*
- * Protect against malicious guests. If the string is not double
- * null terminated, ignore it completely.
- */
-
- if (result[len - 1] || result[len - 2]) {
- Warning("%s called with non-double null terminated string!\n",
- __FUNCTION__);
-
- return;
- }
-
- /*
- * Parse the result
- */
-
- for (buf = result; *buf; buf += strlen(buf) + 1) {
- UnityUpdate update;
- Bool ok = FALSE;
-
- if (StrUtil_StartsWith(buf, "add ")) {
- const char *argumentStart = buf + strlen("add ");
- unsigned int index = 0;
-
- DynBuf_Init(&update.u.addWindow.windowPathUtf8);
- DynBuf_Init(&update.u.addWindow.execPathUtf8);
-
- /*
- * The arguments take the form 'add <id> [arguments]' where [arguments] are
- * space seperated 'key=value' pairs, if an argument is simply key= the value
- * should be treated as an empty string.
- * Only the <id> may be present if the guest is running certain older
- * versions of tools.
- */
- ok = StrUtil_GetNextUintToken(&id, &index, argumentStart, " ");
-
- /*
- * If we failed to get the required <id> argument there's little point
- * carrying on. However failure to receive any of the following arguments
- * is not an error (they're optional) - it's also not an error to get
- * an expected key here since we may well add new keys in the future and
- * don't want to log needless error messages if the host hasn't been updated
- * to match.
- */
- if (ok) {
- char *field;
- update.type = UNITY_UPDATE_ADD_WINDOW;
- update.u.addWindow.id = id;
- while ((field = StrUtil_GetNextToken(&index, argumentStart, " "))) {
-
- if (StrUtil_StartsWith(field, "windowPath=")) {
- ok = DynBuf_AppendString(&update.u.addWindow.windowPathUtf8,
- field + strlen("windowPath="));
- }
-
- if (StrUtil_StartsWith(field, "execPath=")) {
- ok = DynBuf_AppendString(&update.u.addWindow.execPathUtf8,
- field + strlen("execPath="));
- }
-
- /*
- * Free the results of the tokenization (field)
- */
- free(field);
- }
- } else {
- LOG(0, ("TOOLS Expected window id but no id found in string.\n"));
- }
- } else if (StrUtil_StartsWith(buf, "remove ")) {
- if (sscanf(buf, "remove %u", &id) == 1) {
- update.type = UNITY_UPDATE_REMOVE_WINDOW;
- update.u.removeWindow.id = id;
- ok = TRUE;
- }
- } else if (StrUtil_StartsWith(buf, "move ")) {
- if (sscanf(buf, "move %u %d %d %d %d", &id, &x1, &y1,
- &x2, &y2) == 5) {
- update.type = UNITY_UPDATE_MOVE_WINDOW;
- update.u.moveWindow.id = id;
- RECT_SETRECT(&update.u.moveWindow.rect, x1, y1, x2, y2);
- ok = TRUE;
- }
- } else if (StrUtil_StartsWith(buf, "title ")) {
- const char *titleInfo = buf + 6;
-
- /* StrUtil_* functions do not like NULL strings. */
- if (*titleInfo) {
- unsigned int index = 0;
- if (StrUtil_GetNextUintToken(&id, &index, titleInfo, " ")) {
- char *titleUtf8 = NULL;
- update.u.changeWindowTitle.id = id;
-
- if (titleInfo[index] == ' ') {
- index++; // Skip the space
- if (titleInfo[index]) {
- titleUtf8 = StrUtil_GetNextToken(&index, titleInfo,
- "");
- }
- }
- if (!titleUtf8) {
- titleUtf8 = Util_SafeStrdup("");
- }
-
- DynBuf_Init(&update.u.changeWindowTitle.titleUtf8);
- if (DynBuf_AppendString(&update.u.changeWindowTitle.titleUtf8,
- titleUtf8)) {
- update.type = UNITY_UPDATE_CHANGE_WINDOW_TITLE;
- ok = TRUE;
- }
- free(titleUtf8);
- } else {
- LOG(0,
- ("TOOLS Malformed title string, couldn't get the window id.\n"));
- }
- } else {
- LOG(0, ("TOOLS Empty title string, couldn't get the title.\n"));
- }
- } else if (StrUtil_StartsWith(buf, "zorder ")) {
- int count = 0;
- int i = 0;
- const char *bufPtr = buf;
- bufPtr = strchr(bufPtr, ' ');
- if (sscanf(bufPtr, " %d", &count) == 1) {
- count = MIN(count, ARRAYSIZE(update.u.zorder.ids));
- bufPtr = strchr(++bufPtr, ' ');
- while (bufPtr && *bufPtr && i < count &&
- sscanf(bufPtr, " %u", update.u.zorder.ids + i) == 1) {
- i++;
- bufPtr = strchr(++bufPtr, ' ');
- }
- if (i == count) {
- update.type = UNITY_UPDATE_CHANGE_ZORDER;
- update.u.zorder.count = count;
- ok = TRUE;
- } else {
- LOG(0, ("TOOLS Expected %d but received %d in zorder string.\n",
- count, i));
- }
- } else {
- LOG(0, ("TOOLS Malformed zorder string, couldn't scan count.\n"));
- }
- } else if (StrUtil_StartsWith(buf, "region ")) {
- int current = 0, numRects;
- if (sscanf(buf, "region %u %d", &id, &numRects) == 2) {
- RegionPtr region = NULL;
-
- update.type = UNITY_UPDATE_CHANGE_WINDOW_REGION;
- update.u.changeWindowRegion.region = NULL;
- update.u.changeWindowRegion.id = id;
-
- if (numRects) {
- BoxRec rc;
- RECT_SETRECT(&rc, 0, 0, 0, 0);
- region = miRegionCreate(&rc, 0);
-
- do {
- buf += strlen(buf) + 1;
- current++;
- if (sscanf(buf, "rect %d %d %d %d", &x1, &y1, &x2, &y2) == 4) {
- RECT_SETRECT(&rc, x1, y1, x2, y2);
- miApplyRect(region, region, &rc, miUnion);
- } else {
- Warning("Malformed processing unity region" \
- " (attempting to continue): %s.\n",
- buf);
- }
- } while (current < numRects && *buf);
- }
- update.u.changeWindowRegion.region = region;
- ok = TRUE;
- } else {
- Warning("Malformed processing unity region %s.\n", buf);
- }
- } else if (StrUtil_StartsWith(buf, "state ")) {
- uint32 state = 0;
-
- update.type = UNITY_UPDATE_CHANGE_WINDOW_STATE;
- if (sscanf(buf, "state %u %d", &id, &state) == 2) {
- update.u.changeWindowState.id = id;
- update.u.changeWindowState.state = state;
- ok = TRUE;
- }
- } else if (StrUtil_StartsWith(buf, "attr ")) {
- update.type = UNITY_UPDATE_CHANGE_WINDOW_ATTRIBUTE;
- if (sscanf(buf, "attr %u %u %u",
- &update.u.changeWindowAttribute.id,
- (unsigned int *)&update.u.changeWindowAttribute.attr,
- &update.u.changeWindowAttribute.value) == 3 &&
- update.u.changeWindowAttribute.attr < UNITY_MAX_ATTRIBUTES) {
- ok = TRUE;
- }
- } else if (StrUtil_StartsWith(buf, "type ")) {
- update.type = UNITY_UPDATE_CHANGE_WINDOW_TYPE;
- if (sscanf(buf, "type %u %d", &update.u.changeWindowType.id,
- (int *)&update.u.changeWindowType.winType) == 2 &&
- update.u.changeWindowType.winType < UNITY_MAX_WINDOW_TYPES) {
- ok = TRUE;
- }
- } else if (StrUtil_StartsWith(buf, "icon ")) {
- update.type = UNITY_UPDATE_CHANGE_WINDOW_ICON;
- if (sscanf(buf, "icon %u %u", &update.u.changeWindowIcon.id,
- (unsigned int *)&update.u.changeWindowIcon.iconType) == 2 &&
- update.u.changeWindowIcon.iconType < UNITY_MAX_ICONS) {
- ok = TRUE;
- }
- } else if (StrUtil_StartsWith(buf, "desktop ")) {
- update.type = UNITY_UPDATE_CHANGE_WINDOW_DESKTOP;
- if (sscanf(buf, "desktop %u %d", &update.u.changeWindowDesktop.id,
- &update.u.changeWindowDesktop.desktopId) == 2) {
- ok = TRUE;
- }
- } else if (StrUtil_StartsWith(buf, "activedesktop ")) {
- update.type = UNITY_UPDATE_CHANGE_ACTIVE_DESKTOP;
- if (sscanf(buf, "activedesktop %d",
- &update.u.changeActiveDesktop.desktopId) == 1) {
- ok = TRUE;
- }
- }
-
- if (ok) {
- (*cb)(param, &update);
- } else {
- Warning("Malformed unity response string: %s.\n", buf);
- }
-
- if (ok && (update.type == UNITY_UPDATE_ADD_WINDOW)) {
- DynBuf_Destroy(&update.u.addWindow.windowPathUtf8);
- DynBuf_Destroy(&update.u.addWindow.execPathUtf8);
- }
-
- if (ok && (update.type == UNITY_UPDATE_CHANGE_WINDOW_TITLE)) {
- DynBuf_Destroy(&update.u.changeWindowTitle.titleUtf8);
- }
-
- if (ok &&
- (update.type == UNITY_UPDATE_CHANGE_WINDOW_REGION) &&
- (update.u.changeWindowRegion.region != NULL)) {
- miRegionDestroy(update.u.changeWindowRegion.region);
- }
- }
- }
-}
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * unityWindowTracker.h --
- *
- * Used to buffer state about a window manager.
- *
- * In general, clients will notify the window tracker of changes to the window
- * manager state via:
- *
- * UnityWindowTracker_AddWindow
- * UnityWindowTracker_RemoveWindow
- * UnityWindowTracker_MoveWindow
- * UnityWindowTracker_ChangeWindowRegion
- * etc. etc.
- *
- * And then call UnityWindowTracker_RequestUpdates to pull a summary of the updates
- * out. The user may call the AddWindow, RemoveWindow, etc functions as often as they
- * like. The window tracker's job is to compress a series of notifications into the
- * smallest delta between updates.
- *
- * Typical use works something like:
- *
- * UnityWindowTracker_Init(...)
- * many times do {
- * many times to {
- * UnityWindowTracker_AddWindow, UnityWindowTracker_MoveWindow, etc.
- * }
- * UnityWindowTracker_RequestUpdates(...)
- * }
- * UnityWindowTracker_Cleanup(...)
- *
- */
-
-#ifndef _UNITY_WINDOW_TRACKER_H_
-#define _UNITY_WINDOW_TRACKER_H_
-
-#include "hashTable.h"
-#include "region.h"
-#include "dynbuf.h"
-#include "unityCommon.h"
-
-/* The maximum number of windows that this tracker can track */
-#define UNITY_MAX_WINDOWS 1024
-
-/*
- * UNITY_CHANGE_* track changes to windows as we're accumulating state for
- * an update.
- */
-#define UNITY_CHANGED_POSITION (1 << 0)
-#define UNITY_CHANGED_REGION (1 << 1)
-#define UNITY_CHANGED_ADDED (1 << 2)
-#define UNITY_CHANGED_REMOVED (1 << 3)
-#define UNITY_CHANGED_TITLE (1 << 4)
-#define UNITY_CHANGED_ZORDER (1 << 5)
-#define UNITY_CHANGED_WINDOW_STATE (1 << 6)
-#define UNITY_CHANGED_WINDOW_ATTRIBUTES (1 << 7)
-#define UNITY_CHANGED_WINDOW_TYPE (1 << 8)
-#define UNITY_CHANGED_WINDOW_ICONS (1 << 9)
-#define UNITY_CHANGED_WINDOW_DESKTOP (1 << 10)
-#define UNITY_CHANGED_ACTIVE_DESKTOP (1 << 11)
-
-/*
- * UNITY_UPDATE_* flags are passed to UnityWindowTracker_RequestUpdates
- */
-#define UNITY_UPDATE_INCREMENTAL (1 << 0)
-#define UNITY_UPDATE_REMOVE_UNTOUCHED (1 << 1)
-
-typedef enum {
- UNITY_WINDOW_ORDER_TOP = 0,
- UNITY_WINDOW_ORDER_BOTTOM = UNITY_MAX_WINDOWS
-} UnityZOrder;
-
-/*
- * Unity callbacks passed to UnityWindowTracker_Init used to notify the
- * caller of changes to the window system.
- */
-typedef enum {
- UNITY_UPDATE_ADD_WINDOW,
- UNITY_UPDATE_MOVE_WINDOW,
- UNITY_UPDATE_REMOVE_WINDOW,
- UNITY_UPDATE_CHANGE_WINDOW_REGION,
- UNITY_UPDATE_CHANGE_WINDOW_TITLE,
- UNITY_UPDATE_CHANGE_ZORDER,
- UNITY_UPDATE_CHANGE_WINDOW_STATE,
- UNITY_UPDATE_CHANGE_WINDOW_ATTRIBUTE,
- UNITY_UPDATE_CHANGE_WINDOW_TYPE,
- UNITY_UPDATE_CHANGE_WINDOW_ICON,
- UNITY_UPDATE_CHANGE_WINDOW_DESKTOP,
- UNITY_UPDATE_CHANGE_ACTIVE_DESKTOP
-} UnityUpdateType;
-
-/*
- * Single UnityUpdate struct that gets passed into the UnityUpdateCallback
- * function. Unity updates have a very long way to travel (tools ->
- * vmx -> mks -> vnc -> (wire) -> vnc -> ui) and having a single callback
- * function greatly reduces the amount of plumbing that has to be written
- * for every singe command.
- */
-
-typedef struct UnityUpdate {
- UnityUpdateType type;
- union {
- struct {
- UnityWindowId id;
- DynBuf windowPathUtf8;
- DynBuf execPathUtf8;
- } addWindow;
-
- struct {
- UnityWindowId id;
- } removeWindow;
-
- struct {
- UnityWindowId id;
- BoxRec rect;
- } moveWindow;
-
- struct {
- UnityWindowId id;
- RegionPtr region;
- } changeWindowRegion;
-
- struct {
- UnityWindowId id;
- DynBuf titleUtf8;
- } changeWindowTitle;
-
- struct {
- uint32 count;
- UnityWindowId ids[UNITY_MAX_WINDOWS];
- } zorder;
-
- struct {
- UnityWindowId id;
- uint32 state;
- } changeWindowState;
-
- struct {
- UnityWindowId id;
- UnityWindowAttribute attr;
- uint32 value;
- } changeWindowAttribute;
-
- struct {
- UnityWindowId id;
- UnityWindowType winType;
- } changeWindowType;
-
- struct {
- UnityWindowId id;
- UnityIconType iconType;
- } changeWindowIcon;
-
- struct {
- UnityWindowId id;
- UnityDesktopId desktopId;
- } changeWindowDesktop;
-
- struct {
- UnityDesktopId desktopId;
- } changeActiveDesktop;
-
- } u;
-} UnityUpdate;
-
-typedef void (*UnityUpdateCallback)(void *param, UnityUpdate *update);
-
-void UnityWindowTracker_ParseUnityUpdate(const char *result,
- int len,
- UnityUpdateCallback cb,
- void *param);
-
-/*
- * Internal state --
- * Do not fiddle with these bits! They are included in this header to aid in debugging.
- * Enjoy looking at them, but consider them READ ONLY (!!)
- *
- */
-
-#define UNITY_INFO_ATTR_EXISTS (1 << 7)
-#define UNITY_INFO_ATTR_CHANGED (1 << 6)
-#define UNITY_INFO_ATTR_ENABLED (1 << 0)
-
-typedef struct {
- UnityWindowId id;
- DynBuf titleUtf8;
- RegionPtr region;
- BoxRec rect;
- uint32 state;
- UnityWindowType type;
- UnityDesktopId desktopId;
- DynBuf windowPathUtf8;
- DynBuf execPathUtf8;
-
- /* Each element is an OR of the UNITY_INFO_ATTR_* values */
- unsigned char attributes[UNITY_MAX_ATTRIBUTES];
- /* Ditto, but only EXISTS and CHANGED apply... */
- unsigned char icons[UNITY_MAX_ICONS];
-
- Bool reap;
- /*
- * Used to track if a window was reported during the last update cycle (whether or not
- * its properties actually changed), so that we can automatically have windows removed
- * in Unity implementations that poll for changes (such as Win32).
- */
- Bool touched;
- /*
- * Used to track which properties of a window changed during the last update cycle.
- */
- int changed;
-
- void *data;
-
- /*
- * This points back to the tracker. It's either this, or a bigger hack in
- * lib/misc/hash.c
- */
- void *tracker;
-} UnityWindowInfo;
-
-typedef struct _UnityWindowTracker UnityWindowTracker;
-
-typedef void (*UnityDataFreeFunc)(UnityWindowTracker *tracker,
- UnityWindowInfo *windowInfo,
- void *data);
-
-struct _UnityWindowTracker {
- HashTable *windows;
- UnityWindowId zorder[UNITY_MAX_WINDOWS];
- uint32 count; // in zorder array
- Bool zorderChanged;
-
- UnityDesktopId activeDesktopId;
- Bool activeDesktopChanged;
-
- /*
- * True if the guest should add hidden windows to the list of tracked windows.
- * The windows will be added to the tracker with the hidden attribute.
- * By default the guest will not add hidden windows to the tracker.
- */
- Bool addHiddenWindows;
-
- void *cbparam;
- UnityUpdateCallback cb;
- uint32 updateFlags;
-
- UnityDataFreeFunc freeFn;
-};
-
-/*
- * Public Functions --
- */
-
-void UnityWindowTracker_Init(UnityWindowTracker *tracker,
- UnityUpdateCallback cb);
-void UnityWindowTracker_Cleanup(UnityWindowTracker *tracker);
-void UnityWindowTracker_SetDataFreeFunc(UnityWindowTracker *tracker,
- UnityDataFreeFunc freeFn);
-UnityWindowInfo *UnityWindowTracker_AddWindow(UnityWindowTracker *tracker,
- UnityWindowId id,
- DynBuf *windowPathUtf8,
- DynBuf *execPathUtf8);
-UnityWindowInfo *UnityWindowTracker_AddWindowWithData(UnityWindowTracker *tracker,
- UnityWindowId id,
- DynBuf *windowPathUtf8,
- DynBuf *execPathUtf8,
- void *data);
-void UnityWindowTracker_MoveWindow(UnityWindowTracker *tracker,
- UnityWindowId id, int x1, int y1, int x2,
- int y2);
-void UnityWindowTracker_ChangeWindowRegion(UnityWindowTracker *tracker,
- UnityWindowId id, RegionPtr region);
-void UnityWindowTracker_RemoveWindow(UnityWindowTracker *tracker,
- UnityWindowId id);
-void UnityWindowTracker_SendUpdate(UnityWindowTracker *tracker,
- UnityUpdate *update);
-void UnityWindowTracker_SetWindowTitle(UnityWindowTracker *tracker,
- UnityWindowId id,
- DynBuf *titleUtf8);
-void UnityWindowTracker_RemoveAllWindows(UnityWindowTracker *tracker);
-
-/*
- * Please note that calling ChangeWindowState directly is deprecated. Use
- * SetWindowAttribute and SetWindowType instead.
- */
-void UnityWindowTracker_ChangeWindowState(UnityWindowTracker *tracker,
- UnityWindowId id,
- uint32 state);
-/*
- * Deprecated. Use GetWindowAttribute and GetWindowType instead.
- */
-Bool UnityWindowTracker_GetWindowState(UnityWindowTracker *tracker,
- UnityWindowId id,
- uint32 *state);
-
-void UnityWindowTracker_ChangeWindowAttribute(UnityWindowTracker *tracker,
- UnityWindowId id,
- UnityWindowAttribute attr,
- Bool enabled);
-Bool UnityWindowTracker_GetWindowAttribute(UnityWindowTracker *tracker,
- UnityWindowId id,
- UnityWindowAttribute attr,
- Bool *enabled);
-void UnityWindowTracker_ChangeWindowType(UnityWindowTracker *tracker,
- UnityWindowId id,
- UnityWindowType winType);
-Bool UnityWindowTracker_GetWindowType(UnityWindowTracker *tracker,
- UnityWindowId id,
- UnityWindowType *winType);
-void UnityWindowTracker_NotifyIconChanged(UnityWindowTracker *tracker,
- UnityWindowId id,
- UnityIconType iconType);
-void UnityWindowTracker_ChangeWindowDesktop(UnityWindowTracker *tracker,
- UnityWindowId id,
- UnityDesktopId desktopId);
-Bool UnityWindowTracker_GetWindowDesktop(UnityWindowTracker *tracker,
- UnityWindowId id,
- UnityDesktopId *desktopId);
-void UnityWindowTracker_ChangeActiveDesktop(UnityWindowTracker *tracker,
- UnityDesktopId desktopId);
-UnityDesktopId UnityWindowTracker_GetActiveDesktop(UnityWindowTracker *tracker);
-void UnityWindowTracker_SetZOrder(UnityWindowTracker *tracker, UnityWindowId zorder[],
- int count);
-void UnityWindowTracker_SetZPosition(UnityWindowTracker *tracker, UnityWindowId window,
- uint32 zorder);
-void UnityWindowTracker_RequestUpdates(UnityWindowTracker *tracker,
- uint32 flags, void *param);
-UnityWindowInfo *UnityWindowTracker_LookupWindow(UnityWindowTracker *tracker,
- UnityWindowId id);
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityWindowTracker_GetWindowData --
- *
- * Returns the app data pointer associated with a particular Unity window.
- *
- * Results:
- * Pointer to the app data. May be NULL if no data is set or 'info' is invalid.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void *
-UnityWindowTracker_GetWindowData(UnityWindowTracker *tracker, // IN
- UnityWindowInfo *info) // IN
-{
- return info ? info->data : NULL;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityWindowTracker_GetWindowDataById --
- *
- * Returns the app data pointer associated with a particular Unity window ID.
- *
- * Results:
- * Pointer to the app data. May be NULL if no data is set or 'info' is invalid.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void *
-UnityWindowTracker_GetWindowDataById(UnityWindowTracker *tracker, // IN
- UnityWindowId winId) // IN
-{
- return UnityWindowTracker_GetWindowData(tracker,
- UnityWindowTracker_LookupWindow(tracker,
- winId));
-}
-#endif
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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 --
- *
- * Debugging functions for unity window manager intergration.
- *
- */
-
-#include "vmware.h"
-#include "debug.h"
-#include "util.h"
-#include "region.h"
-#include "unityPlatform.h"
-#include "unityWindowTracker.h"
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityDebug_Init --
- *
- * One time initialization stuff. Create our Window GDI objects.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityDebug_Init(UnityWindowTracker *tracker) // IN
-{
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityDebug_OnUpdate --
- *
- * Called everytime we get an update request from the tools. Just
- * invalidate the debug window to trigger a repaint.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityDebug_OnUpdate(void)
-{
-}
+++ /dev/null
-/*********************************************************
- * 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 event.cc
- *
- * Provides code relating the Glib main loop and Xlib/X11 event sources.
- */
-
-
-extern "C" {
- #include <stdlib.h>
- #include <stdio.h>
- #include "vmware.h"
-}
-
-#include "x11Platform.h"
-
-
-/*
- * File scope prototypes.
- */
-
-
-static void ConnectionWatch(Display *display, XPointer client_data, int fd,
- int opening, XPointer *watch_data);
-static gboolean TeardownHashRemove(gpointer key, gpointer value,
- gpointer user_data);
-static gboolean USourcePrepare(GSource *source, gint *timeout);
-static gboolean USourceCheck(GSource *source);
-static gboolean USourceDispatch(GSource *source, GSourceFunc callback,
- gpointer cbData);
-
-
-/*
- * Library scope functions.
- */
-
-
-/*
- ******************************************************************************
- * UnityX11EstablishSource -- */ /**
- *
- * @brief Creates Glib event source for X11 events. Attaches to the Glib event
- * loop.
- *
- * @param[in] up Our Unity platform context.
- *
- ******************************************************************************
- */
-
-void
-UnityX11EventEstablishSource(UnityPlatform *up) // IN
-{
- static GSourceFuncs unitySourceFuncs = {0};
- unitySourceFuncs.prepare = USourcePrepare;
- unitySourceFuncs.check = USourceCheck;
- unitySourceFuncs.dispatch = USourceDispatch;
-
- UnityGSource *uSource;
-
- ASSERT(up);
- ASSERT(up->display);
-
- uSource = (UnityGSource *)g_source_new(&unitySourceFuncs, sizeof *uSource);
- uSource->up = up;
- uSource->fdTable = g_hash_table_new(g_direct_hash, g_direct_equal);
-
- up->glibSource = uSource;
-
- /* Hook our main X11 connection into our event source. */
- ConnectionWatch(up->display, (XPointer)up, ConnectionNumber(up->display), TRUE,
- NULL);
-
- /* If Xlib opens an internal connection, bind it to the source, too. */
- XAddConnectionWatch(up->display, &ConnectionWatch, (XPointer)up);
-
- /* Attach the source to the event loop. */
- g_source_set_callback((GSource*)uSource, UnityX11HandleEvents, up, NULL);
- g_source_attach((GSource*)uSource, NULL);
-
- /* Transfer ownership to the event loop. */
- g_source_unref((GSource*)uSource);
-}
-
-
-/*
- ******************************************************************************
- * UnityX11TeardownSource -- */ /**
- *
- * @brief Detach Unity from our Glib event loop.
- *
- * @param[in] up Our Unity platform context.
- *
- ******************************************************************************
- */
-
-void
-UnityX11EventTeardownSource(UnityPlatform *up) // IN
-{
- UnityGSource *uSource = up->glibSource;
-
- ASSERT(up);
- ASSERT(uSource);
-
- /* Detach Xlib internal connection notification from the Glib event loop. */
- XRemoveConnectionWatch(up->display, &ConnectionWatch, (XPointer)up);
-
- /* Detach all Xlib file descriptors from our Glib event source. */
- g_hash_table_foreach_remove(uSource->fdTable, TeardownHashRemove, uSource);
- g_hash_table_unref(uSource->fdTable);
- uSource->fdTable = NULL;
-
- /* Destroy the Glib event source. */
- g_source_destroy((GSource*)uSource);
- up->glibSource = NULL;
-}
-
-
-/*
- * File scope functions.
- */
-
-
-/*
- ******************************************************************************
- * ConnectionWatch -- */ /**
- *
- * @brief Binds Xlib internal connections to Glib event sources.
- *
- * When Xlib or its extensions create new X11 connections, they're bound to
- * a @a Display as <em>"internal connections"</em>. When Xlib processes the
- * incoming event queue, it pulls requests from @em all of these connections,
- * not just the main event connection. As such, we should monitor all of
- * them.
- *
- * @param[in] display X11 display context.
- * @param[in] client_data Our UnityPlatform context.
- * @param[in] fd Relevant file descriptor.
- * @param[in] opening TRUE when @a fd is opened, FALSE when @a fd is closed.
- * @param[in] watch_data Unused.
- *
- * @sa XAddConnectionWatch
- *
- ******************************************************************************
- */
-
-static void
-ConnectionWatch(Display *display, // IN
- XPointer client_data, // IN
- int fd, // IN
- int opening, // IN
- XPointer *watch_data) // UNUSED
-{
- UnityPlatform *up;
- UnityGSource *uSource;
-
- up = (UnityPlatform *)client_data;
-
- ASSERT(up); // Make sure we're correctly registered.
- ASSERT(up->isRunning); // This cb should be stripped before we exit Unity.
- ASSERT(up->glibSource); // This function is useless w/o an established source.
- ASSERT(display == up->display);
-
- uSource = up->glibSource;
-
- if (opening) {
- /*
- * Add new a new file descriptor to the poll array.
- */
- GPollFD *newFd = g_new0(GPollFD, 1);
-
- ASSERT(g_hash_table_lookup(uSource->fdTable, GINT_TO_POINTER(fd)) == NULL);
-
- newFd->fd = fd;
- newFd->events = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
-
- g_hash_table_insert(uSource->fdTable, GINT_TO_POINTER(fd), newFd);
- g_source_add_poll((GSource*)uSource, newFd);
- } else {
- /*
- * Remove a file descriptor from the poll array.
- */
- GPollFD *oldFd = (GPollFD*)g_hash_table_lookup(uSource->fdTable, GINT_TO_POINTER(fd));
-
- if (oldFd) {
- g_source_remove_poll((GSource *)uSource, oldFd);
- g_hash_table_remove(uSource->fdTable, GINT_TO_POINTER(fd));
- g_free(oldFd);
- }
- }
-}
-
-
-/*
- ******************************************************************************
- * TeardownHashRemove -- */ /**
- *
- * @brief Assists TeardownSource with destroying its GPollFD hash table.
- *
- * @param[in] key GINT_TO_POINTER-converted file descriptor.
- * @param[in] value Corresponding GPollFD *.
- * @param[in] user_data Our UnityGSource.
- *
- * @see g_hash_table_foreach_remove
- *
- ******************************************************************************
- */
-
-static gboolean
-TeardownHashRemove(gpointer key, // IN
- gpointer value, // IN
- gpointer user_data) // IN
-{
- GPollFD *oldFd = (GPollFD*)value;
- UnityGSource *uSource = (UnityGSource*)user_data;
-
- ASSERT(value);
- ASSERT(user_data);
-
- g_source_remove_poll((GSource *)uSource, oldFd);
- g_free(oldFd);
-
- return TRUE;
-}
-
-
-/*
- ******************************************************************************
- * USourcePrepare -- */ /**
- *
- * @brief See GSourceFuncs::prepare.
- *
- * @param[in] source Points to our UnityGSource.
- * @param[out] timeout May specify a maximum timeout value for poll(2).
- *
- * @retval TRUE Source is ready.
- * @retval FALSE Source not yet ready.
- *
- ******************************************************************************
- */
-
-static gboolean
-USourcePrepare(GSource *source, // IN
- gint *timeout) // OUT
-{
- UnityGSource *uSource = (UnityGSource *)source;
-
- /*
- * "It sets the returned timeout to -1 to indicate that it doesn't mind how
- * long the poll() call blocks."
- * - http://library.gnome.org/devel/glib/unstable/glib-The-Main-Event-Loop.html#GSourceFuncs
- */
- *timeout = -1;
-
- return XQLength(uSource->up->display) > 0;
-}
-
-
-/*
- ******************************************************************************
- * USourceCheck -- */ /**
- *
- * @brief See GSourceFuncs::check.
- *
- * @param[in] source Points to our UnityGSource.
- *
- * @retval TRUE Source is ready.
- * @retval FALSE Source not yet ready.
- *
- * @todo Should exit Unity upon file descriptor error.
- *
- ******************************************************************************
- */
-
-static gboolean
-USourceCheck(GSource *source) // IN
-{
- UnityGSource *uSource = (UnityGSource *)source;
- gboolean haveData = FALSE;
-
- /*
- * XXX Could/should test for FD errors here.
- */
- if (XQLength(uSource->up->display)) {
- haveData = TRUE;
- } else {
- GList *pollFds;
- GList *listIter;
-
- pollFds = g_hash_table_get_values(uSource->fdTable);
-
- for (listIter = pollFds; listIter; listIter = listIter->next) {
- GPollFD *pollFd = (GPollFD*)listIter->data;
-
- if (pollFd->revents & G_IO_IN) {
- haveData = TRUE;
- break;
- }
- }
-
- g_list_free(pollFds);
- }
-
- return haveData;
-}
-
-
-/*
- ******************************************************************************
- * USourceDispatch -- */ /**
- *
- * @brief See GSourceFuncs::dispatch.
- *
- * @param[in] source Points to our UnityGSource.
- * @param[in] callback Points to the user's callback.
- * @param[in] cbData Points to user's callback data.
- *
- * @retval TRUE Glib should continue monitoring the source.
- * @retval FALSE Glib should stop monitoring the source.
- *
- ******************************************************************************
- */
-
-static gboolean
-USourceDispatch(GSource *source, // IN
- GSourceFunc callback, // IN
- gpointer cbData) // IN
-{
- /*
- * Remind callers to attach a callback.
- */
- ASSERT(callback);
- ASSERT(cbData);
-
- return callback(cbData);
-}
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007-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.
- *
- *********************************************************/
-
-/*
- * settings.cc --
- *
- * Handles saving and restoring various system settings that are needed for Unity to
- * work well.
- */
-
-#include "x11Platform.h"
-
-#if !defined(VM_HAVE_X11_SS_EXT) && !defined(USING_AUTOCONF)
- #error "We're not building with the X11 ScreenSaver extension."
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GetScreensaverActive --
- *
- * Finds out whether the screensaver is currently enabled.
- *
- * Results:
- * TRUE if successful, FALSE otherwise
- *
- * Side effects:
- * Stores the current setting in *currentSetting
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GetScreensaverActive(UnityPlatform *up, // IN
- Bool *currentSetting) // OUT
-{
- int timeout;
- int dummy;
-
- ASSERT(up);
- ASSERT(currentSetting);
-
- *currentSetting = FALSE;
-
-#if defined(VM_HAVE_X11_SS_EXT)
- {
- int eventBase;
- int errorBase;
- if (XScreenSaverQueryExtension(up->display, &eventBase, &errorBase)) {
- XScreenSaverInfo saverInfo;
-
- if (!XScreenSaverQueryInfo(up->display,
- DefaultRootWindow(up->display),
- &saverInfo)) {
- return FALSE;
- }
-
- *currentSetting = (saverInfo.state != ScreenSaverDisabled);
- }
- }
-#endif
-
- timeout = -1;
- XGetScreenSaver(up->display, &timeout, &dummy, &dummy, &dummy);
-
- if(timeout == -1) {
- return FALSE;
- }
-
- *currentSetting = *currentSetting || (timeout ? TRUE : FALSE);
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * SetScreensaverActive --
- *
- * Enables/disables the screensaver.
- *
- * Results:
- * TRUE if successful, FALSE otherwise
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-SetScreensaverActive(UnityPlatform *up, // IN
- Bool currentSetting) // IN
-{
- int timeout = -1; // If XGetScreenSaver fails, use the default
- int interval = 0;
- int preferBlanking = DefaultBlanking;
- int allowExposures = DefaultExposures;
- char *xdgScreensaverPath;
-
- ASSERT(up);
-
- /*
- * There are currently three ways to enable/disable the screensaver (in order of
- * current preference):
- *
- * 1. The xdg-screensaver script that knows how to talk to the screensavers of most
- * current desktops.
- * 2. XScreenSaverSuspend, via the X screensaver extension.
- * 3. XSetScreenSaver.
- *
- * Only the first one actually works on most systems, but the other two are there to
- * catch corner cases on odd systems.
- */
-
- xdgScreensaverPath = g_find_program_in_path("xdg-screensaver");
- if (up->rootWindows && xdgScreensaverPath) {
- char rootWindowID[64];
- char *argv[] = {xdgScreensaverPath,
- (char*)(currentSetting ? "resume" : "suspend"),
- rootWindowID,
- NULL};
-
- g_snprintf(rootWindowID, sizeof rootWindowID, "%#lx", up->rootWindows->windows[0]);
-
- g_spawn_sync("/", argv, NULL, (GSpawnFlags)0, NULL, NULL, NULL, NULL, NULL, NULL);
- }
- g_free(xdgScreensaverPath);
-
-#if defined(VM_HAVE_X11_SS_EXT)
- {
- int eventBase;
- int errorBase;
-
- if (!XScreenSaverQueryExtension(up->display, &eventBase, &errorBase)) {
- return FALSE;
- }
- /*
- * XScreenSaverSuspend is only available as of version 1.1 of the screensaver
- * extension
- */
-# if (ScreenSaverMajorVersion > 1 \
- || (ScreenSaverMajorVersion == 1 && ScreenSaverMinorVersion >= 1))
- {
- int majorVersion;
- int minorVersion;
-
- if (XScreenSaverQueryVersion(up->display, &majorVersion, &minorVersion)
- && (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 1))) {
-
- XScreenSaverSuspend(up->display, !currentSetting);
- up->currentSettings[UNITY_UI_SCREENSAVER] = currentSetting;
- }
- }
-# endif
-
- /*
- * XXX TODO: On systems that don't have XScreenSaverSuspend, we could always monitor
- * ScreenSaverNotify events, and send a ForceScreenSaver request (with value of Reset)
- * whenever the screensaver comes on.
- */
- }
-#endif
-
- XGetScreenSaver(up->display, &timeout, &interval, &preferBlanking, &allowExposures);
-
- if (!currentSetting) {
- up->savedScreenSaverTimeout = timeout; // Save the old timeout.
- timeout = 0; // Disables the screensaver.
- } else {
- timeout = up->savedScreenSaverTimeout;
- up->savedScreenSaverTimeout = -1;
- }
-
- XSetScreenSaver(up->display, timeout, interval, preferBlanking, allowExposures);
-
- if (!currentSetting) {
- /*
- * Disable the screen saver if it's already active.
- */
- XForceScreenSaver(up->display, ScreenSaverReset);
- }
-
- return TRUE;
-}
-
-
-#ifdef VM_UNIMPLEMENTED_UNITY_SETTINGS
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GetDropShadowActive --
- *
- * Finds out whether drop shadows are currently enabled.
- *
- * Results:
- * TRUE if successful, FALSE otherwise
- *
- * Side effects:
- * Stores the current setting in *currentSetting
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GetDropShadowActive(UnityPlatform *up, // IN
- Bool *currentSetting) // OUT
-{
- ASSERT(up);
- ASSERT(currentSetting);
-
- NOT_IMPLEMENTED();
-
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * SetDropShadowActive --
- *
- * Enables/disables drop shadows.
- *
- * Results:
- * TRUE if successful, FALSE otherwise
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-SetDropShadowActive(UnityPlatform *up, // IN
- Bool currentSetting) // IN
-{
- ASSERT(up);
-
- up->currentSettings[UNITY_UI_DROP_SHADOW] = currentSetting;
-
- NOT_IMPLEMENTED();
-
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GetMenuAnimationActive --
- *
- * Finds out whether menu animation is currently enabled.
- *
- * Results:
- * TRUE if successful, FALSE otherwise
- *
- * Side effects:
- * Stores the current setting in *currentSetting
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GetMenuAnimationActive(UnityPlatform *up, // IN
- Bool *currentSetting) // OUT
-{
- ASSERT(up);
- ASSERT(currentSetting);
-
- NOT_IMPLEMENTED();
-
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * SetMenuAnimationActive --
- *
- * Enables/disables the screensaver.
- *
- * Results:
- * TRUE if successful, FALSE otherwise
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-SetMenuAnimationActive(UnityPlatform *up, // IN
- Bool currentSetting) // IN
-{
- ASSERT(up);
-
- up->currentSettings[UNITY_UI_MENU_ANIMATION] = currentSetting;
-
- NOT_IMPLEMENTED();
-
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GetTooltipAnimationActive --
- *
- * Finds out whether the screensaver is currently enabled.
- *
- * Results:
- * TRUE if successful, FALSE otherwise
- *
- * Side effects:
- * Stores the current setting in *currentSetting
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GetTooltipAnimationActive(UnityPlatform *up, // IN
- Bool *currentSetting) // OUT
-{
- ASSERT(up);
- ASSERT(currentSetting);
-
- NOT_IMPLEMENTED();
-
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * SetTooltipAnimationActive --
- *
- * Enables/disables the screensaver.
- *
- * Results:
- * TRUE if successful, FALSE otherwise
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-SetTooltipAnimationActive(UnityPlatform *up, // IN
- Bool currentSetting) // IN
-{
- ASSERT(up);
-
- up->currentSettings[UNITY_UI_TOOLTIP_ANIMATION] = currentSetting;
-
- NOT_IMPLEMENTED();
-
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GetWindowAnimationActive --
- *
- * Finds out whether the screensaver is currently enabled.
- *
- * Results:
- * TRUE if successful, FALSE otherwise
- *
- * Side effects:
- * Stores the current setting in *currentSetting
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GetWindowAnimationActive(UnityPlatform *up, // IN
- Bool *currentSetting) // OUT
-{
- ASSERT(up);
- ASSERT(currentSetting);
-
- NOT_IMPLEMENTED();
-
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * SetWindowAnimationActive --
- *
- * Enables/disables the screensaver.
- *
- * Results:
- * TRUE if successful, FALSE otherwise
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-SetWindowAnimationActive(UnityPlatform *up, // IN
- Bool currentSetting) // IN
-{
- ASSERT(up);
-
- up->currentSettings[UNITY_UI_WINDOW_ANIMATION] = currentSetting;
-
- NOT_IMPLEMENTED();
-
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GetFullWindowDragActive --
- *
- * Finds out whether the screensaver is currently enabled.
- *
- * Results:
- * TRUE if successful, FALSE otherwise
- *
- * Side effects:
- * Stores the current setting in *currentSetting
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GetFullWindowDragActive(UnityPlatform *up, // IN
- Bool *currentSetting) // OUT
-{
- ASSERT(up);
- ASSERT(currentSetting);
-
- NOT_IMPLEMENTED();
-
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * SetFullWindowDragActive --
- *
- * Enables/disables the screensaver.
- *
- * Results:
- * TRUE if successful, FALSE otherwise
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-SetFullWindowDragActive(UnityPlatform *up, // IN
- Bool currentSetting) // IN
-{
- ASSERT(up);
-
- up->currentSettings[UNITY_UI_FULL_WINDOW_DRAG] = currentSetting;
-
- NOT_IMPLEMENTED();
-
- return FALSE;
-}
-
-
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * GetTaskbarVisible --
- *
- * Shows or hides the taskbar as appropriate.
- *
- * Results:
- * TRUE if successful, FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-GetTaskbarVisible(UnityPlatform *up, // IN
- Bool *currentSetting) // OUT
-{
- UnityPlatformWindow **allWindows;
- size_t i;
- size_t numWindows;
-
- ASSERT(up);
- ASSERT(currentSetting);
-
- numWindows = 0;
- HashTable_ToArray(up->allWindows,
- (void ***)&allWindows,
- &numWindows);
-
- if (!numWindows) {
- Debug("Couldn't find any listed windows for taskbar visibility detection.\n");
- return FALSE; // We haven't yet populated the window list for some reason
- }
-
- /*
- * Hunt through all the windows for ones that are of type DOCK.
- */
- *currentSetting = FALSE;
- for (i = 0; i < numWindows; i++) {
- if (UNITY_WINDOW_TYPE_DOCK == allWindows[i]->windowType
- && allWindows[i]->isViewable) {
- *currentSetting = TRUE;
- break;
- }
- }
-
- free(allWindows);
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformSetTaskbarVisible --
- *
- * Shows or hides the taskbar as appropriate.
- *
- * Results:
- * TRUE if successful, FALSE otherwise.
- *
- * Side effects:
- * Shows or hides task bar.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformSetTaskbarVisible(UnityPlatform *up, // IN
- Bool currentSetting) // IN
-{
- UnityPlatformWindow **allWindows;
- size_t i;
- size_t numWindows;
-
- ASSERT(up);
-
- up->needTaskbarSetting = FALSE;
-
- up->currentSettings[UNITY_UI_TASKBAR_VISIBLE] = currentSetting;
-
- numWindows = 0;
- HashTable_ToArray(up->allWindows,
- (void ***) &allWindows,
- &numWindows);
-
- /*
- * Hunt through all the windows for ones that are of type DOCK.
- */
- for (i = 0; i < numWindows; i++) {
- if (UNITY_WINDOW_TYPE_DOCK == allWindows[i]->windowType) {
- Window dockWindow;
- UnityPlatformWindow *upw = allWindows[i];
-
- dockWindow = upw->clientWindow;
- if (!dockWindow) {
- dockWindow = upw->toplevelWindow;
- }
-
- if (currentSetting) {
- /*
- * If this flag is still set, that means that this window is being
- * remapped -before- we received a _NET_WM_DESKTOP PropertyDelete
- * notification. (One such case may be if exiting Unity before the
- * PropertyDelete is delivered.) In that case, we'll go ahead and
- * reset the property ourselves before remapping.
- */
- if (upw->wantSetDesktopNumberOnUnmap) {
- UPWindow_SetEWMHDesktop(up, upw, upw->onUnmapDesktopNumber);
- upw->wantSetDesktopNumberOnUnmap = FALSE;
- }
- XMapWindow(up->display, dockWindow);
- } else {
- /* Preserve _NET_WM_DESKTOP across unmap. */
- if (!upw->wantSetDesktopNumberOnUnmap) {
- upw->wantSetDesktopNumberOnUnmap = TRUE;
- upw->onUnmapDesktopNumber = upw->desktopNumber;
- }
- XWithdrawWindow(up->display, dockWindow, 0);
- }
-
- UPWindow_CheckRelevance(up, upw, NULL);
- }
- }
-
- free(allWindows);
-
- if (!numWindows) {
- /*
- * We need to repeat this call later.
- */
- up->needTaskbarSetting = TRUE;
- }
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * SaveVirtualDesktopSettings --
- *
- * Saves the current virtual desktop configuration so it can be restored later on.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-SaveVirtualDesktopSettings(UnityPlatform *up) // IN
-{
- ASSERT(up);
-
- up->desktopInfo.savedNumDesktops = UnityPlatformGetNumVirtualDesktops(up);
- UnityPlatformGetVirtualDesktopLayout(up, up->desktopInfo.savedLayoutData);
- up->desktopInfo.savedCurrentDesktop = UnityX11GetCurrentDesktop(up);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * RestoreVirtualDesktopSettings --
- *
- * Restores the saved virtual desktop configuration.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Guest's virtual desktop config may be changed.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-RestoreVirtualDesktopSettings(UnityPlatform *up) // IN
-{
- size_t tempDesktops;
- ASSERT(up);
-
- memcpy(up->desktopInfo.layoutData,
- up->desktopInfo.savedLayoutData,
- sizeof up->desktopInfo.layoutData);
- tempDesktops = up->desktopInfo.numDesktops;
- up->desktopInfo.numDesktops = up->desktopInfo.savedNumDesktops;
- UnityPlatformSyncDesktopConfig(up);
-
- /*
- * ...because numDesktops also refers to the size of the guestDesktopToUnity and
- * unityDesktopToGuest arrays.
- */
- up->desktopInfo.numDesktops = tempDesktops;
-
- UnityX11SetCurrentDesktop(up, up->desktopInfo.savedCurrentDesktop);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformSaveSystemSettings --
- *
- * Stub to make unity.c happy. This function is called at a very inconvenient time
- * for the X11 port, so I just call its UnityX11 equivalent at the appropriate point
- * in StartHelperThreads instead.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformSaveSystemSettings(UnityPlatform *up) // IN
-{
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityX11SaveSystemSettings --
- *
- * Save and disable certain system settings here:
- * a. If a screen saver is enabled, disable it
- * b. If animation for menus or tooltips is enabled, disable it
- * c. If menu shading is enabled, disable it
- * d. If full window drag is disabled, enable it
- * e. If window animation is enabled, disable it
- * f. Hide the task bar.
- *
- * Right now on X11, only the screensaver and task bar make any sense.
- *
- * Remember all the settings changed above in a bit mask,
- * so we can restore them later when the user exits
- * the Unity mode.
- *
- * Note, that the system ui changes made here will not
- * persist after the system reboot.
- *
- * Results:
- * None.
- *
- * Side effects:
- * A bunch of system ui settings might be changed.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityX11SaveSystemSettings(UnityPlatform *up) // IN
-{
- ASSERT(up);
-
- /*
- * We only want to remember current settings if we do not have saved settings already.
- * One of the reasons why we might have saved settings already is because we are
- * re-entering unity without cleanly exiting it first (if the VM was suspended). In
- * this case, theoretically, all the right settings are set already and
- * up->originalSettings contains the original user settings that we do not want to
- * overwrite.
- */
- if (!up->haveOriginalSettings) {
- Bool *originalSettings = up->originalSettings;
-
- memset(up->originalSettings, 0, sizeof up->originalSettings);
-
- if (!GetScreensaverActive(up, &originalSettings[UNITY_UI_SCREENSAVER])) {
- originalSettings[UNITY_UI_SCREENSAVER] = TRUE;
- }
-
-#ifdef VM_UNIMPLEMENTED_UNITY_SETTINGS
- if (!GetDropShadowActive(up, &originalSettings[UNITY_UI_DROP_SHADOW])) {
- originalSettings[UNITY_UI_DROP_SHADOW] = TRUE;
- }
-
- if (!GetMenuAnimationActive(up, &originalSettings[UNITY_UI_MENU_ANIMATION])) {
- originalSettings[UNITY_UI_MENU_ANIMATION] = TRUE;
- }
-
- if (!GetTooltipAnimationActive(up,
- &originalSettings[UNITY_UI_TOOLTIP_ANIMATION])) {
- originalSettings[UNITY_UI_TOOLTIP_ANIMATION] = TRUE;
- }
-
- if (!GetWindowAnimationActive(up, &originalSettings[UNITY_UI_WINDOW_ANIMATION])) {
- originalSettings[UNITY_UI_WINDOW_ANIMATION] = TRUE;
- }
-
- if (!GetFullWindowDragActive(up, &originalSettings[UNITY_UI_FULL_WINDOW_DRAG])) {
- originalSettings[UNITY_UI_FULL_WINDOW_DRAG] = TRUE;
- }
-#endif
-
- if (!GetTaskbarVisible(up, &originalSettings[UNITY_UI_TASKBAR_VISIBLE])) {
- originalSettings[UNITY_UI_TASKBAR_VISIBLE] = TRUE;
- }
-
- SaveVirtualDesktopSettings(up);
-
- up->haveOriginalSettings = TRUE;
-
- memcpy(up->currentSettings, originalSettings, sizeof up->currentSettings);
- }
-
- SetScreensaverActive(up, FALSE);
-#ifdef VM_UNIMPLEMENTED_UNITY_SETTINGS
- SetDropShadowActive(up, FALSE);
- SetMenuAnimationActive(up, FALSE);
- SetTooltipAnimationActive(up, FALSE);
- SetWindowAnimationActive(up, FALSE);
- SetFullWindowDragActive(up, FALSE);
-#endif
-
- {
- char *reply = NULL;
- size_t replyLen;
- Bool shouldBeVisible = FALSE;
-
- if (!RpcOut_sendOne(&reply, &replyLen, UNITY_RPC_VMX_SHOW_TASKBAR)) {
- Debug("%s: could not get the VMX show taskbar setting, assuming FALSE\n",
- __FUNCTION__);
- } else {
- uint32 value = 0;
-
- if (StrUtil_StrToUint(&value, reply)) {
- shouldBeVisible = (value == 0) ? FALSE : TRUE;
- }
- }
-
- Debug("TASKBAR SHOULD BE VISIBLE: %d\n", shouldBeVisible);
-
- UnityPlatformSetTaskbarVisible(up, shouldBeVisible);
-
- free(reply);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformRestoreSystemSettings --
- *
- * Stub to make unity.c happy. This function is called at a very inconvenient time
- * for the X11 port, so I just call its UnityX11 equivalent at the appropriate point
- * in KillHelperThreads instead.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformRestoreSystemSettings(UnityPlatform *up) // IN
-{
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityX11RestoreSystemSettings --
- *
- * Restore system ui settings to what they used to be
- * before we entered unity mode.
- *
- * This includes:
- * a. Enable screen saver if it was disabled
- * b. Enable menu and tool tip animation if it was disabled
- * c. Enable menu shading is enabled if it was disabled
- * d. Disable full window drag is disabled if it was enabled
- * e. Enable window animation if it was disabled
- * f. Show the task bar if it was hidden
- *
- * Results:
- * None.
- *
- * Side effects:
- * A bunch of system ui settings might be changed.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityX11RestoreSystemSettings(UnityPlatform *up) // IN
-{
- ASSERT(up);
-
- Debug("UnityPlatformRestoreSystemSettings\n");
- if (up->currentSettings[UNITY_UI_SCREENSAVER]
- != up->originalSettings[UNITY_UI_SCREENSAVER]) {
- SetScreensaverActive(up, up->originalSettings[UNITY_UI_SCREENSAVER]);
- Debug("%s: Restored screen saver\n", __FUNCTION__);
- }
-
-#ifdef VM_UNIMPLEMENTED_UNITY_SETTINGS
- if (up->currentSettings[UNITY_UI_DROP_SHADOW]
- != up->originalSettings[UNITY_UI_DROP_SHADOW]) {
- SetDropShadowActive(up, up->originalSettings[UNITY_UI_DROP_SHADOW]);
- Debug("%s: Restored drop shadows\n", __FUNCTION__);
- }
-
- if (up->currentSettings[UNITY_UI_MENU_ANIMATION]
- != up->originalSettings[UNITY_UI_MENU_ANIMATION]) {
- SetMenuAnimationActive(up, up->originalSettings[UNITY_UI_MENU_ANIMATION]);
- Debug("%s: Restored menu animation\n", __FUNCTION__);
- }
-
- if (up->currentSettings[UNITY_UI_TOOLTIP_ANIMATION]
- != up->originalSettings[UNITY_UI_TOOLTIP_ANIMATION]) {
- SetTooltipAnimationActive(up, up->originalSettings[UNITY_UI_TOOLTIP_ANIMATION]);
- Debug("%s: Restored tool tip animation\n", __FUNCTION__);
- }
-
- if (up->currentSettings[UNITY_UI_WINDOW_ANIMATION]
- != up->originalSettings[UNITY_UI_WINDOW_ANIMATION]) {
- SetWindowAnimationActive(up, up->originalSettings[UNITY_UI_WINDOW_ANIMATION]);
- Debug("%s: Restored window animation\n", __FUNCTION__);
- }
-
- if (up->currentSettings[UNITY_UI_FULL_WINDOW_DRAG]
- != up->originalSettings[UNITY_UI_FULL_WINDOW_DRAG]) {
- SetFullWindowDragActive(up, up->originalSettings[UNITY_UI_FULL_WINDOW_DRAG]);
- Debug("%s: Restored outline drag.\n", __FUNCTION__);
- }
-#endif
-
- if (up->currentSettings[UNITY_UI_TASKBAR_VISIBLE]
- != up->originalSettings[UNITY_UI_TASKBAR_VISIBLE]) {
- UnityPlatformSetTaskbarVisible(up, up->originalSettings[UNITY_UI_TASKBAR_VISIBLE]);
- Debug("%s: Restored taskbar visibility.\n", __FUNCTION__);
- }
-
- RestoreVirtualDesktopSettings(up);
-
- /*
- * The user's settings have been restored, which means the originalSettings info will
- * not be relevant next time we go into SaveSystemSettings().
- */
- up->haveOriginalSettings = FALSE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformShowTaskbar --
- *
- * Show/hide the taskbar while in Unity mode.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformShowTaskbar(UnityPlatform *up, // IN
- Bool showTaskbar) // IN
-{
- ASSERT(up);
-
- /*
- * If we are in Unity mode, we need to hide/show the taskbar.
- * If the user asked to show the taskbar and the taskbar was previously hidden,
- * we need to show the taskbar and readjust the work area.
- * Other cases (when the taskbar is already shown and user wants to show it,
- * for example), should theoretically never happen, but if they do, we just
- * ignore them because there's not much we can do.
- */
-
- if (UnityPlatformIsUnityRunning(up)) {
- Debug("Host asked us to show the taskbar %d\n", showTaskbar);
- UnityPlatformSetTaskbarVisible(up, showTaskbar);
- } else {
- Debug("%s: We are not in Unity mode, ignore the show taskbar command\n",
- __FUNCTION__);
- }
-
- UnityPlatformDoUpdate(up, TRUE);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformShowDesktop --
- *
- * Show/hide the entire VM desktop while in Unity mode.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformShowDesktop(UnityPlatform *up, // IN
- Bool showDesktop) // IN
-{
- ASSERT(up);
- NOT_IMPLEMENTED();
-}
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/**
- * @file unity.c
- *
- * Unity: Guest window manager integration service.
- *
- * This file implements the guest-side Unity agent generally used as part of the
- * Tools Core Services Unity plugin. It contains the platform-agnostic entry points
- * for Unity window operations and establishes the context for the platform specific
- * window enumeration process that exports data from the guest window tracker to
- * the host.
- *
- * UnityWindowTracker updates are sent to the MKS in two ways:
- * @li @ref UNITY_RPC_GET_UPDATE GuestRpc (host-to-guest).
- * @li @ref UNITY_RPC_PUSH_UPDATE_CMD GuestRpc (guest-to-host).
- *
- * @note Looking for the old "unity.get.update" return syntax? See @ref
- * UNITY_RPC_GET_UPDATE and @ref UnityGetUpdateReturn instead.
- *
- * @sa
- * @li UnityRpcHG
- * @li UnityRpcGH
- */
-
-#include "vmware.h"
-#include "debug.h"
-#include "unityDebug.h"
-#include "unityInt.h"
-#include "unityPlatform.h"
-
-/*
- * Singleton object for tracking the state of the service.
- */
-UnityState unity;
-
-/*
- * Helper Functions
- */
-static void UnityUpdateCallbackFn(void *param, UnityUpdate *update);
-static void UnitySetAddHiddenWindows(Bool enabled);
-static void UnitySetInterlockMinimizeOperation(Bool enabled);
-static void UnitySetSendWindowContents(Bool enabled);
-static void UnitySetDisableCompositing(Bool disabled);
-
-/*
- * Dispatch table for Unity window commands. All commands performing actions on
- * guest unity windows go here.
- */
-typedef struct {
- const char *name;
- Bool (*exec)(UnityPlatform *up, UnityWindowId window);
-} UnityCommandElem;
-
-static UnityCommandElem unityCommandTable[] = {
- { UNITY_RPC_WINDOW_CLOSE, UnityPlatformCloseWindow },
- { UNITY_RPC_WINDOW_SHOW, UnityPlatformShowWindow },
- { UNITY_RPC_WINDOW_HIDE, UnityPlatformHideWindow },
- { UNITY_RPC_WINDOW_MINIMIZE, UnityPlatformMinimizeWindow },
- { UNITY_RPC_WINDOW_UNMINIMIZE, UnityPlatformUnminimizeWindow },
- { UNITY_RPC_WINDOW_MAXIMIZE, UnityPlatformMaximizeWindow },
- { UNITY_RPC_WINDOW_UNMAXIMIZE, UnityPlatformUnmaximizeWindow },
- { UNITY_RPC_WINDOW_STICK, UnityPlatformStickWindow },
- { UNITY_RPC_WINDOW_UNSTICK, UnityPlatformUnstickWindow },
- /* Add more commands and handlers above this. */
- { NULL, NULL }
-};
-
-/*
- * A list of the commands implemented in this library - this list should
- * match the command dispatch table.
- */
-static char* unityCommandList[] = {
- UNITY_RPC_WINDOW_CLOSE,
- UNITY_RPC_WINDOW_SHOW,
- UNITY_RPC_WINDOW_HIDE,
- UNITY_RPC_WINDOW_MINIMIZE,
- UNITY_RPC_WINDOW_UNMINIMIZE,
- UNITY_RPC_WINDOW_MAXIMIZE,
- UNITY_RPC_WINDOW_UNMAXIMIZE,
- UNITY_RPC_WINDOW_STICK,
- UNITY_RPC_WINDOW_UNSTICK,
- /* Add more commands above this. */
- NULL
-};
-
-typedef struct {
- uint32 featureBit;
- void (*setter)(Bool enabled);
-} UnityFeatureSetter;
-
-/*
- * Dispatch table for each unity option and a specific function to handle enabling
- * or disabling the option. The function is called with an enable (TRUE) bool value.
- */
-static UnityFeatureSetter unityFeatureTable[] = {
- { UNITY_ADD_HIDDEN_WINDOWS_TO_TRACKER, UnitySetAddHiddenWindows },
- { UNITY_INTERLOCK_MINIMIZE_OPERATION, UnitySetInterlockMinimizeOperation },
- { UNITY_SEND_WINDOW_CONTENTS, UnitySetSendWindowContents },
- { UNITY_DISABLE_COMPOSITING_IN_GUEST, UnitySetDisableCompositing },
- /* Add more Unity Feature Setters above this. */
- {0, NULL}
-};
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_IsSupported --
- *
- * Determine whether this guest supports unity.
- *
- * Results:
- * TRUE if the guest supports Unity (i.e. if the guest is WinXP) or
- * if the option to always enable unity was specified in the tools
- * configuration file
- * FALSE otherwise
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_IsSupported(void)
-{
- return UnityPlatformIsSupported() || unity.forceEnable;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_IsActive --
- *
- * Determine whether we are in Unity mode at this moment.
- *
- * Results:
- * TRUE if Unity is active.
- * FALSE is Unity is not active.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_IsActive(void)
-{
- return unity.isEnabled;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Unity_Init --
- *
- * One time initialization stuff.
- *
- *
- * Results:
- * None.
- *
- * Side effects:
- * May register with the tools poll loop.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Unity_Init(UnityHostCallbacks hostCallbacks) // IN
-{
- Debug("Unity_Init\n");
-
- ASSERT(hostCallbacks.updateCB);
- ASSERT(hostCallbacks.buildUpdateCB);
- ASSERT(hostCallbacks.sendWindowContents);
- ASSERT(hostCallbacks.sendRequestMinimizeOperation);
- ASSERT(hostCallbacks.shouldShowTaskbar);
-
- unity.hostCallbacks = hostCallbacks;
-
- /*
- * Initialize the UnityWindowTracker object. The uwt does all the actual work
- * of computing differences between two states of the windowing system. The
- * callbacks we register here will fire when we request an update via
- * UnityWindowTracker_RequestUpdates. See bora/lib/unityWindowTracker for more
- * information.
- */
- UnityWindowTracker_Init(&unity.tracker, UnityUpdateCallbackFn);
-
- /*
- * Initialize the platform-specific portion of the unity service.
- */
- unity.up = UnityPlatformInit(&unity.tracker, unity.hostCallbacks);
-
- unity.virtDesktopArray.desktopCount = 0;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Unity_Cleanup --
- *
- * Exit Unity and do final cleanup.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Unity_Cleanup()
-{
- UnityPlatform *up;
-
- Debug("%s\n", __FUNCTION__);
-
-
- /*
- * Exit Unity.
- */
- Unity_Exit();
-
- /*
- * Do one-time final platform-specific cleanup.
- */
- up = unity.up;
- unity.up = NULL;
- if (NULL != up) {
- UnityPlatformCleanup(up);
- }
- UnityWindowTracker_Cleanup(&unity.tracker);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Unity_SetActiveDnDDetWnd --
- *
- * Right now we have 2 Unity DnD full screen detection window, one for version
- * 2 or older, another for version 3 or newer. This function is to set active
- * one according to host DnD version.
- *
- * XXX Both full-screent window is still bottom-most and is showed all time
- * during Unity mode. Another change is needed to change it to only show the
- * window during guest->host DnD. Also the window should not be bottom-most,
- * but dynamicly change z-order during DnD.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Unity_SetActiveDnDDetWnd(UnityDnD *state)
-{
- if (unity.up != NULL) {
- UnityPlatformSetActiveDnDDetWnd(unity.up, state);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Unity_Exit --
- *
- * Called everytime we exit Unity. This function can be called when we are
- * not in Unity mode. Right now it is called every time a 'reset' TCLO command
- * is sent to the guest. Therefore, there's no guarantee that we were in the
- * Unity mode when this function is called.
- *
- * Try to do the following:
- * Restore system settings if needed.
- * Hide the unity dnd detection window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Restores system settings since we are exiting Unity.
- * Hides the unity dnd detection window if needed.
- * Sets unity.isEnabled to FALSE
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Unity_Exit(void)
-{
- int featureIndex = 0;
-
- if (unity.isEnabled) {
- /*
- * Reset any Unity Options - they'll be re-enabled as required before the
- * next UnityTcloEnter.
- */
- while (unityFeatureTable[featureIndex].featureBit != 0) {
- if (unity.currentOptions & unityFeatureTable[featureIndex].featureBit) {
- unityFeatureTable[featureIndex].setter(FALSE);
- }
- featureIndex++;
- }
- unity.currentOptions = 0;
-
- /* Hide full-screen detection window for Unity DnD. */
- UnityPlatformUpdateDnDDetWnd(unity.up, FALSE);
-
- UnityPlatformExitUnity(unity.up);
-
- /* Restore previously saved user settings. */
- UnityPlatformRestoreSystemSettings(unity.up);
-
- unity.isEnabled = FALSE;
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Unity_Enter --
- *
- * Called everytime we enter Unity.
- *
- * Try to do the following:
- * Save the system settings.
- * Show the unity dnd detection window.
- *
- * Results:
- * TRUE if Unity was entered.
- *
- * Side effects:
- * Sets unity.isEnabled to TRUE.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-Unity_Enter(void)
-{
- if (!unity.isEnabled) {
- /* Save and disable certain user settings here. */
- UnityPlatformSaveSystemSettings(unity.up);
-
- if (!UnityPlatformEnterUnity(unity.up)) {
- UnityPlatformExitUnity(unity.up);
- UnityPlatformRestoreSystemSettings(unity.up);
- return FALSE;
- }
-
- /*
- * Show full-screen detection window for Unity DnD. It is a bottom-most (but
- * still in front of desktop) transparent detection window for guest->host DnD
- * as drop target. We need this window because:
- * 1. All active windows except desktop will be shown on host desktop and can
- * accept DnD signal. This full-screen detection window will block any DnD signal
- * (even mouse signal) to the desktop, which will fix bug 164880.
- * 2. With this full-screen but bottommost detection window, every time when user
- * drag something out from active window, the dragEnter will always be immediately
- * catched for Unity DnD.
- */
- UnityPlatformUpdateDnDDetWnd(unity.up, TRUE);
- unity.isEnabled = TRUE;
- }
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_GetWindowCommandList --
- *
- * Retrieve the list of command strings supported by this library. The
- * commands are a list of strings which each operate on a specified Unity
- * window ID to perform operations like unmiminimize or restore.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-Unity_GetWindowCommandList(char ***commandList) // OUT
-{
- ASSERT(commandList != NULL);
-
- *commandList = unityCommandList;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_GetWindowPath --
- *
- * Get the information needed to re-launch a window and retrieve further information
- * on it. windowPathUtf8 and execPathUtf8 allow a platform to specify different
- * null terminated strings for the 'path' to the window vs. the path to the
- * executable that launched the window. The exact meaning of the buffer contents
- * is platform-specific.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_GetWindowPath(UnityWindowId window, // IN: window handle
- DynBuf *windowPathUtf8, // IN/OUT: full path for the window
- DynBuf *execPathUtf8) // IN/OUT: full path for the executable
-{
- return UnityPlatformGetWindowPath(unity.up, window, windowPathUtf8, execPathUtf8);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_WindowCommand --
- *
- * Execute the specified command for the given window ID.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_WindowCommand(UnityWindowId window, // IN: window handle
- const char *command) // IN: Command name
-{
- unsigned int i;
- ASSERT(command);
-
- for (i = 0; unityCommandTable[i].name != NULL; i++) {
- if (strcmp(unityCommandTable[i].name, command) == 0) {
- if (!unityCommandTable[i].exec(unity.up, window)) {
- Debug("%s: Unity window command %s failed.\n", __FUNCTION__, command);
- return FALSE;
- } else {
- return TRUE;
- }
- }
- }
-
- Debug("%s: Invalid command %s\n", __FUNCTION__, command);
- return FALSE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_SetDesktopWorkAreas --
- *
- * Sets the work areas for all screens. These are the areas
- * to which windows will maximize.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_SetDesktopWorkAreas(UnityRect workAreas[], // IN
- uint32 numWorkAreas) // IN
-{
- uint32 i;
-
- for (i = 0; i < numWorkAreas; i++) {
- if (workAreas[i].x < 0 || workAreas[i].y < 0 ||
- workAreas[i].width <= 0 || workAreas[i].height <= 0) {
- Debug("%s: Invalid work area\n", __FUNCTION__);
- return FALSE;
- }
- }
-
- return UnityPlatformSetDesktopWorkAreas(unity.up, workAreas, numWorkAreas);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_SetTopWindowGroup --
- *
- * Set the group of windows on top of all others.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_SetTopWindowGroup(UnityWindowId windows[], // IN: array of window ids
- unsigned int windowCount) // IN: # of windows in the array
-{
- return UnityPlatformSetTopWindowGroup(unity.up, windows, windowCount);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_GetUpdate --
- *
- * This function is used to asynchronously collect Unity window updates
- * and send them to the host via the guest->host channel.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-Unity_GetUpdate(Bool incremental) // IN: Incremental vs. full update
-{
- UnityPlatformDoUpdate(unity.up, incremental);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_ConfirmOperation --
- *
- * Confirmation from the host that an operation requiring interlock has been
- * completed by the host.
- *
- * Results:
- * TRUE if the confirmation could be handled sucessfully.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_ConfirmOperation(unsigned int operation, // IN
- UnityWindowId windowId, // IN
- uint32 sequence, // IN
- Bool allow) // IN
-{
- Bool retVal = FALSE;
-
- if (MINIMIZE == operation) {
- retVal = UnityPlatformConfirmMinimizeOperation(unity.up,
- windowId,
- sequence,
- allow);
- } else {
- Debug("%s: Confirmation for unknown operation ID = %d\n", __FUNCTION__, operation);
- }
- return retVal;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_SendMouseWheel --
- *
- * Sends the given mouse wheel event to the window at the given location.
- *
- * Results:
- * TRUE on success, FALSE on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_SendMouseWheel(int32 deltaX, // IN
- int32 deltaY, // IN
- int32 deltaZ, // IN
- uint32 modifierFlags) // IN
-{
- return UnityPlatformSendMouseWheel(unity.up, deltaX, deltaY, deltaZ, modifierFlags);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_GetUpdates --
- *
- * Get the unity window update and append it to the specified output buffer.
- * This function can be called from two different threads: either from
- * the main thread that is trying to execute a TCLO command (unity.get.update)
- * or from the unity update thread that is gathering periodic updates and
- * pushes them to the VMX as needed (by calling 'tools.unity.push.update RPC).
- * Since this function can be called from two different threads, protect
- * the global unity singleton with locks.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-Unity_GetUpdates(int flags) // IN: unity update flags
-{
- UnityPlatformLock(unity.up);
-
- /*
- * Generate the update stream. This will cause our UnityUpdateCallbackFn to be
- * triggered, which will in turn lead to the callback registered with the
- * 'consumer' of this library which will do the actual update serialization.
- */
- UnityWindowTracker_RequestUpdates(&unity.tracker, flags, unity.up);
-
- UnityPlatformUnlock(unity.up);
-
- return;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityUpdateCallbackFn --
- *
- * Callback from the unity window tracker indicating something has
- * changed.
- *
- * Perform any internal functions we need called as a consequence of tracker
- * window state changing and then call the provided callback to serialize the
- * update.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Clearly.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityUpdateCallbackFn(void *param, // IN: UnityPlatform
- UnityUpdate *update) // IN
-{
- unity.hostCallbacks.updateCB(unity.hostCallbacks.updateCbCtx, update);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_GetWindowContents --
- *
- * Read the correct bits off the window regardless of whether it's minimized
- * or obscured. Return the result as a PNG in the imageData DynBuf.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- * imageData contains PNG formatted window contents.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_GetWindowContents(UnityWindowId window, // IN
- DynBuf *imageData, // IN/OUT
- uint32 *width, // OUT
- uint32 *height) // OUT
-{
- return UnityPlatformGetWindowContents(unity.up, window, imageData, width, height);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_GetIconData --
- *
- * Read part or all of a particular icon on a window. Return the result as a PNG in
- * the imageData DynBuf, and also return the full length of the PNG in fullLength.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_GetIconData(UnityWindowId window, // IN
- UnityIconType iconType, // IN
- UnityIconSize iconSize, // IN
- uint32 dataOffset, // IN
- uint32 dataLength, // IN
- DynBuf *imageData, // OUT
- uint32 *fullLength) // OUT
-{
- return UnityPlatformGetIconData(unity.up, window, iconType, iconSize,
- dataOffset, dataLength, imageData, fullLength);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_ShowTaskbar --
- *
- * Show/hide the taskbar while in Unity mode.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-Unity_ShowTaskbar(Bool showTaskbar) // IN
-{
- UnityPlatformShowTaskbar(unity.up, showTaskbar);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Unity_ShowDesktop --
- *
- * Shows or hides the entire VM desktop while in unity. This is useful for
- * situations where the user must interact with a window that we cannot
- * control programmatically, such as UAC prompts on Vista and Win7.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Unity_ShowDesktop(Bool showDesktop) // IN
-{
- UnityPlatformShowDesktop(unity.up, showDesktop);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_MoveResizeWindow --
- *
- * Moves and/or resizes the given window to the specified location. Does not
- * attempt to move and/or resize window if (a) the destination rectangle does not
- * intersect with the virtual screen rectangle, or (b) window is minimized.
- *
- * If the input width & height match the current width & height, then this
- * function will end up just moving the window. Similarly if the input
- * x & y coordinates match the current coordinates, then it will end up just
- * resizing the window.
- *
- * Results:
- * Even if the move/resize operation is not executed or it fails, window's
- * current coordinates are always sent back.
- *
- * Function does not return FALSE if the attempt to move and/or resize fails.
- * This is because the caller will be comparing input and output parameters to
- * decide whether the window really moved and/or resized.
- *
- * In a very rare case, when attempt to get window's current coordinates fail,
- * returns FALSE.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_MoveResizeWindow(UnityWindowId window, // IN: Window handle
- UnityRect *moveResizeRect) // IN/OUT: Desired coordinates,
- // before and after the operation.
-{
- return UnityPlatformMoveResizeWindow(unity.up, window, moveResizeRect);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_SetDesktopConfig --
- *
- * Set the virtual desktop configuration as specified by the host.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_SetDesktopConfig(const UnityVirtualDesktopArray *desktopConfig) // IN
-{
- if (UnityPlatformSetDesktopConfig(unity.up, desktopConfig)) {
- unity.virtDesktopArray = *desktopConfig;
- return TRUE;
- }
- return FALSE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_SetDesktopActive --
- *
- * Switch to the specified virtual desktop.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * Might change the active virtual desktop in the guest.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_SetDesktopActive(UnityDesktopId desktopId) // IN: Index into desktop config. array
-{
- if (desktopId >= unity.virtDesktopArray.desktopCount) {
- Debug("%s: Desktop (%d) does not exist in the guest", __FUNCTION__, desktopId);
- return FALSE;
- }
-
- return UnityPlatformSetDesktopActive(unity.up, desktopId);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_SetWindowDesktop --
- *
- * Move the window to the specified desktop. The desktopId is an index
- * into the desktop configuration array.
- *
- * Results:
- * TRUE if everything is successful.
- * FALSE otherwise.
- *
- * Side effects:
- * Might change the active virtual desktop in the guest.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_SetWindowDesktop(UnityWindowId windowId, // IN
- UnityDesktopId desktopId) // IN
-{
- if (desktopId >= unity.virtDesktopArray.desktopCount) {
- Debug("%s: The desktop (%d) does not exist in the guest", __FUNCTION__, desktopId);
- return FALSE;
- }
-
- /*
- * Set the desktop id for this window in the tracker.
- * We need to do this before moving the window since on MS Windows platforms
- * moving the window will hide it and there's a danger that we may enumerate the
- * hidden window before changing it's desktop ID. The Window tracker will ignore
- * hidden windows on the current desktop - which ultimately can lead to this window
- * being reaped from the tracker.
- */
- UnityWindowTracker_ChangeWindowDesktop(&unity.tracker, windowId, desktopId);
-
- return UnityPlatformSetWindowDesktop(unity.up, windowId, desktopId);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_SetUnityOptions --
- *
- * Set the Unity options - must be be called before entering Unity mode.
- * UnityFeatures is a bitmask of features to be enabled (see unityCommon.h)
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-Unity_SetUnityOptions(uint32 newFeaturesMask) // IN: UnityFeatures
-{
- int featureIndex = 0;
- uint32 featuresChanged;
-
- if (unity.isEnabled) {
- Debug("%s: Attempting to set unity options whilst unity is enabled\n",
- __FUNCTION__);
- }
-
- /*
- * For each potential feature bit XOR the current mask with the newly
- * specified set, then if the bit has changed call the specific setter
- * function with TRUE/FALSE according to the new state of the bit.
- */
- featuresChanged = newFeaturesMask ^ unity.currentOptions;
- while (unityFeatureTable[featureIndex].featureBit != 0) {
- if (featuresChanged & unityFeatureTable[featureIndex].featureBit) {
- unityFeatureTable[featureIndex].setter(
- (newFeaturesMask & unityFeatureTable[featureIndex].featureBit) != 0);
- }
- featureIndex++;
- }
-
- unity.currentOptions = newFeaturesMask;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_RequestWindowContents --
- *
- * Add the requeste window IDs to a list of windows whose contents should
- * be sent to the host. See also hostcallbacks.sendWindowContents().
- *
- * Results:
- * TRUE if all the window IDs are valid.
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-Unity_RequestWindowContents(UnityWindowId windowIds[], // IN
- uint32 numWindowIds) // IN)
-{
- return UnityPlatformRequestWindowContents(unity.up, windowIds, numWindowIds);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnitySetAddHiddenWindows --
- *
- * Set (or unset) whether hidden windows should be added to the tracker.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnitySetAddHiddenWindows(Bool enabled)
-{
- /*
- * Should we add hidden windows to the tracker (the host will use the trackers
- * attribute field to display hidden windows in the appropriate manner.)
- */
- if (enabled) {
- Debug("%s: Adding hidden windows to tracker\n", __FUNCTION__);
- } else {
- Debug("%s: Do not add hidden windows to tracker\n", __FUNCTION__);
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnitySetInterlockMinimizeOperation --
- *
- * Set (or unset) whether window operations should be denied/delayed and
- * relayed to the host for later confirmation.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnitySetInterlockMinimizeOperation(Bool enabled)
-{
- /*
- * Should we interlock operations through the host. For example: instead of
- * allowing minimize to occur immediately in the guest should we prevent the
- * minimize of a window in the guest, then relay the minimize to the host and wait
- * for the hosts confirmation before actually minimizing the window in the guest.
- */
- if (enabled) {
- Debug("%s: Interlocking minimize operations through the host\n",
- __FUNCTION__);
- } else {
- Debug("%s: Do not interlock minimize operations through the host\n",
- __FUNCTION__);
- }
- UnityPlatformSetInterlockMinimizeOperation(unity.up, enabled);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnitySetSendWindowContents --
- *
- * Set (or unset) whether window contents should be sent to the host.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnitySetSendWindowContents(Bool enabled)
-{
- /*
- * Is the host prepared to receive scraped window contents at any time - even though
- * it may not have previously requested the window contents. Explicit requests from
- * the host will always be honored - this flag determines whether the guest will send
- * the window contents directly after a qualifying operation (like changes in the
- * z-order of a window).
- */
- if (enabled) {
- Debug("%s: Sending window contents to the host on appropriate events\n",
- __FUNCTION__);
- } else {
- Debug("%s: Do not send window contents to the host on appropriate events\n",
- __FUNCTION__);
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnitySetDisableCompositing --
- *
- * Set (or unset) whether the compositing features of the guest window
- * manager should be disabled.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnitySetDisableCompositing(Bool disabled)
-{
- /*
- * Does the host wish us to disable the compositing features of the guest window
- * manager. The flag only takes effect on subsequent 'enter unity' calls where
- * it is checked and used to disable compositing in the platform layer.
- */
- if (disabled) {
- Debug("%s: Window compositing will be disabled in the guest window manager.\n",
- __FUNCTION__);
- } else {
- Debug("%s: Window compositing will be enabled in the guest window manager.\n",
- __FUNCTION__);
- }
- UnityPlatformSetDisableCompositing(unity.up, disabled);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Unity_SetConfigDesktopColor --
- *
- * Set the preferred desktop background color for use when in Unity Mode. Only
- * takes effect the next time unity mode is entered.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Unity_SetConfigDesktopColor(int desktopColor) // IN
-{
- UnityPlatformSetConfigDesktopColor(unity.up, desktopColor);
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * Unity_SetInitialDesktop --
- *
- * Set a desktop specified by the desktop id as the initial state.
- *
- * Results:
- * Returns TRUE if successful, and FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-Unity_SetInitialDesktop(UnityDesktopId desktopId) // IN
-{
- return UnityPlatformSetInitialDesktop(unity.up, desktopId);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Unity_SetForceEnable --
- *
- * Set's the flag to indicate that Unity should be forced to be enabled, rather
- * than relying on runtime determination of the state of other dependancies.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Unity_SetForceEnable(Bool forceEnable) // IN
-{
- unity.forceEnable = forceEnable;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Unity_InitializeDebugger --
- *
- * Initialize the Unity Debugger. This is a graphical display inside the guest
- * used to visualize the current state of the unity window tracker.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Unity_InitializeDebugger(void)
-{
- UnityDebug_Init(&unity.tracker);
-}
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * unity.h --
- *
- * Commands for unity window manager intergration.
- */
-
-#ifndef _UNITY_H_
-#define _UNITY_H_
-
-#include <glib.h>
-#include "dndGuest.h"
-#include "dynbuf.h"
-#ifdef _WIN32
- #include "libExport.hh"
-#endif
-#include "unityWindowTracker.h"
-
-/*
- * In Unity mode, all our DnD detection windows will be ignored and not displayed
- * on host desktop. Right now we have 4 DnD detection window. 2 for DnD version 2
- * or older, 2 for DnD version 3 or newer.
- */
-enum {
- UNITY_BLOCKED_WND_DND_FULL_DET_V2 = 0,
- UNITY_BLOCKED_WND_DND_DET_V2 = 1,
- UNITY_BLOCKED_WND_DND_FULL_DET_V3 = 2,
- UNITY_BLOCKED_WND_DND_DET_V3 = 3,
- UNITY_BLOCKED_WND_MAX = 4,
-};
-
-/*
- * Maximum number of virtual desktops supported.
- */
-#define MAX_VIRT_DESK 64
-
-/*
- * Represents a virtual desktop coordinates in the virtual desktop grid.
- * The grid might look like {1,1} {1,2} {2,1} {2,2} or {1,1} {1,2} {1,2} etc.
- */
-typedef struct UnityVirtualDesktop {
- int32 x;
- int32 y;
-} UnityVirtualDesktop;
-
-typedef struct UnityPoint {
- int32 x;
- int32 y;
-} UnityPoint;
-
-/*
- * Rectangle on the Unity desktop (typically relative to the Unity Desktop origin.
- * Width & Height must be positive.
- */
-typedef struct {
- int x;
- int y;
- int width;
- int height;
-} UnityRect;
-
-/*
- * Represents a virtual desktop configuration.
- */
-typedef struct UnityVirtualDesktopArray {
- size_t desktopCount; // number of desktops in the grid
- UnityVirtualDesktop desktops[MAX_VIRT_DESK]; // array of desktops
-} UnityVirtualDesktopArray;
-
-/*
- * Callback functions for outbound updates from the guest to the host.
- * The Unity library requires these functions to be provided so that the host
- * is correctly updated as to changes of window state (essentially relaying the
- * Unity protocol to the host).
- *
- * Prepares, builds and sends a sequence of Unity Window Tracker updates back
- * to the host. flags is passed back to the UnityWindowTracker_RequestUpdates()
- * function to set what type of updates are
- * required - see bora/lib/public/unityWindowTracker.h
- */
-typedef Bool (*UnityHostChannelBuildUpdateCallback)(void *param, int flags);
-
-/*
- * Sends the provided window contents (a PNG Image) for the specified WindowID
- * to the host. A FALSE return indicates the contents were not sent correctly.
- */
-typedef Bool (*UnitySendWindowContentsFn)(UnityWindowId windowID,
- uint32 imageWidth,
- uint32 imageHeight,
- const char *imageData,
- uint32 imageLength);
-
-/*
- * Notifies the host that the specified window would like to be minimized, the
- * sequence number is returned in a subsequent confirmation. A FALSE return indicates
- * the contents were not sent correctly.
- */
-typedef Bool (*UnitySendRequestMinimizeOperationFn)(UnityWindowId windowId,
- uint32 sequence);
-/*
- * Sends a (synchronous) inquiry to the host as to whether the guest taskbar
- * should be visible. A FALSE return indicates that the bar should not be shown,
- * no errors are returned from this function - the default behaviour is to not show
- * the task bar in the guest.
- */
-typedef Bool (*UnityShouldShowTaskbarFn)(void);
-
-typedef struct UnityHostCallbacks {
- UnityHostChannelBuildUpdateCallback buildUpdateCB;
- UnityUpdateCallback updateCB; // From UnityWindowTracker.h
- UnitySendWindowContentsFn sendWindowContents;
- UnitySendRequestMinimizeOperationFn sendRequestMinimizeOperation;
- UnityShouldShowTaskbarFn shouldShowTaskbar;
-
- // Context/Cookie passed to buildUpdateCB and updateCB
- void *updateCbCtx;
-} UnityHostCallbacks;
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-void Unity_Init(UnityHostCallbacks hostCallbacks);
-Bool Unity_IsActive(void);
-Bool Unity_IsSupported(void);
-Bool Unity_Enter(void);
-void Unity_Exit(void);
-void Unity_Cleanup(void);
-void Unity_UnityToLocalPoint(UnityPoint *localPt, UnityPoint *unityPt);
-void Unity_LocalToUnityPoint(UnityPoint *unityPt, UnityPoint *localPt);
-void Unity_GetWindowCommandList(char ***commandList);
-void Unity_SetActiveDnDDetWnd(UnityDnD *state);
-
-#ifdef _WIN32
-LIB_EXPORT HWND Unity_GetHwndFromUnityId(UnityWindowId id);
-#endif
-
-void Unity_SetUnityOptions(uint32 newFeaturesMask);
-
-/*
- * Retrieve window metadata, contents, icons, path to owning window.
- */
-Bool Unity_RequestWindowContents(UnityWindowId windowIds[], uint32 numWindowIds);
-Bool Unity_GetWindowContents(UnityWindowId window,
- DynBuf *imageData,
- uint32 *width,
- uint32 *height);
-Bool Unity_GetIconData(UnityWindowId window,
- UnityIconType iconType,
- UnityIconSize iconSize,
- uint32 dataOffset,
- uint32 dataLength,
- DynBuf *imageData,
- uint32 *fullLength);
-Bool Unity_GetWindowPath(UnityWindowId window,
- DynBuf *windowPathUtf8,
- DynBuf *execPathUtf8);
-
-/*
- * Desktop Appearance.
- */
-void Unity_ShowTaskbar(Bool showTaskbar);
-void Unity_SetConfigDesktopColor(int desktopColor);
-void Unity_ShowDesktop(Bool showDesktop);
-
-/*
- * Post a request to asynchronously retrieve Unity updates, or synchronously
- * receive them via the updateChannel.
- */
-void Unity_GetUpdate(Bool incremental);
-void Unity_GetUpdates(int flags);
-
-/*
- * Virtual Desktop configuration and window location.
- */
-Bool Unity_SetDesktopConfig(const UnityVirtualDesktopArray *desktopConfig);
-Bool Unity_SetInitialDesktop(UnityDesktopId desktopId);
-Bool Unity_SetDesktopActive(UnityDesktopId desktopId);
-Bool Unity_SetWindowDesktop(UnityWindowId windowId, UnityDesktopId desktopId);
-Bool Unity_SetDesktopWorkAreas(UnityRect workAreas[], uint32 numWorkAreas);
-Bool Unity_MoveResizeWindow(UnityWindowId window,
- UnityRect *moveResizeRect);
-
-/*
- * Window state, grouping and order.
- */
-Bool Unity_WindowCommand(UnityWindowId window, const char *command);
-Bool Unity_SetTopWindowGroup(UnityWindowId windows[], unsigned int windowCount);
-
-/*
- * Interlocked operations.
- */
-Bool Unity_ConfirmOperation(unsigned int operation,
- UnityWindowId windowId,
- uint32 sequence,
- Bool allow);
-
-/*
- * Mouse Wheel event forwarding.
- */
-Bool Unity_SendMouseWheel(int32 deltaX, int32 deltaY, int32 deltaZ, uint32 modifierFlags);
-
-/*
- * Debugging aids.
- */
-void Unity_SetForceEnable(Bool forceEnable);
-void Unity_InitializeDebugger(void);
-
-#ifdef __cplusplus
-};
-#endif // __cplusplus
-#endif
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/*
- * unityDebug.h --
- *
- * Debugging functions for unity window manager intergration.
- * On in VMX86_DEVEL builds only.
- */
-
-#ifndef _UNITY_DEBUG_H_
-#define _UNITY_DEBUG_H_
-
-#include "unityWindowTracker.h"
-
-#if defined(VMX86_DEVEL)
-void UnityDebug_Init(UnityWindowTracker *tracker);
-void UnityDebug_OnUpdate(void);
-#else
-# define UnityDebug_Init(tracker)
-# define UnityDebug_OnUpdate()
-#endif
-
-
-#endif
-
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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.
- *
- *********************************************************/
-
-#ifndef _UNITYINT_H_
-#define _UNITYINT_H_
-
-/**
- * @file unityInt.h
- *
- * Internal function prototypes.
- *
- * @addtogroup vmtools_plugins
- * @{
- */
-
-#include "unityWindowTracker.h"
-#include "unity.h"
-#include "unityPlatform.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-/*
- * Singleton object for tracking the state of the service.
- */
-typedef struct UnityState {
- UnityWindowTracker tracker;
- Bool forceEnable;
- Bool isEnabled;
- uint32 currentOptions; // Last feature mask received via 'set.options'
- UnityVirtualDesktopArray virtDesktopArray; // Virtual desktop configuration
- UnityHostCallbacks hostCallbacks; // Callbacks to the host for unity updates
- UnityPlatform *up; // Platform-specific state
-} UnityState;
-
-extern UnityState unity;
-
-#ifdef __cplusplus
-};
-#endif // __cplusplus
-
-#endif // _UNITYINT_H_
+++ /dev/null
-/*********************************************************
- * 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.
- *
- *********************************************************/
-
-/**
- * @file unityPlatform.h
- *
- * Implementation specific functionality
- */
-
-#ifndef _UNITYPLATFORM_H_
-#define _UNITYPLATFORM_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-#include "unityWindowTracker.h"
-#include "unity.h"
-#ifdef __cplusplus
-};
-#endif // __cplusplus
-
-typedef struct _UnityPlatform UnityPlatform;
-
-/*
- * Implemented by unityPlatform[Win32|X11|Cocoa (ha!)].c
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-Bool UnityPlatformIsSupported(void);
-UnityPlatform *UnityPlatformInit(UnityWindowTracker *tracker,
- UnityHostCallbacks hostCallbacks);
-void UnityPlatformCleanup(UnityPlatform *up);
-Bool UnityPlatformEnterUnity(UnityPlatform *up);
-void UnityPlatformExitUnity(UnityPlatform *up);
-Bool UnityPlatformUpdateWindowState(UnityPlatform *up,
- UnityWindowTracker *tracker);
-void UnityPlatformSaveSystemSettings(UnityPlatform *up);
-void UnityPlatformRestoreSystemSettings(UnityPlatform *up);
-Bool UnityPlatformGetWindowPath(UnityPlatform *up,
- UnityWindowId window,
- DynBuf *windowPathUtf8,
- DynBuf *execPathUtf8);
-Bool UnityPlatformGetBinaryInfo(UnityPlatform *up,
- const char *pathUtf8,
- DynBuf *buf);
-Bool UnityPlatformSetTopWindowGroup(UnityPlatform *up,
- UnityWindowId *windows,
- unsigned int windowCount);
-Bool UnityPlatformCloseWindow(UnityPlatform *up, UnityWindowId window);
-Bool UnityPlatformShowWindow(UnityPlatform *up, UnityWindowId window);
-Bool UnityPlatformHideWindow(UnityPlatform *up, UnityWindowId window);
-Bool UnityPlatformMinimizeWindow(UnityPlatform *up, UnityWindowId window);
-Bool UnityPlatformUnminimizeWindow(UnityPlatform *up, UnityWindowId window);
-Bool UnityPlatformMaximizeWindow(UnityPlatform *up, UnityWindowId window);
-Bool UnityPlatformUnmaximizeWindow(UnityPlatform *up, UnityWindowId window);
-Bool UnityPlatformGetWindowContents(UnityPlatform *up,
- UnityWindowId window,
- DynBuf *imageData,
- uint32 *width,
- uint32 *height);
-Bool UnityPlatformMoveResizeWindow(UnityPlatform *up,
- UnityWindowId window,
- UnityRect *moveResizeRect);
-void UnityPlatformShowTaskbar(UnityPlatform *up, Bool showTaskbar);
-void UnityPlatformShowDesktop(UnityPlatform *up, Bool showDesktop);
-Bool UnityPlatformGetIconData(UnityPlatform *up,
- UnityWindowId window,
- UnityIconType iconType,
- UnityIconSize iconSize,
- uint32 dataOffset,
- uint32 dataLength,
- DynBuf *imageData,
- uint32 *fullLength);
-Bool UnityPlatformSetDesktopWorkAreas(UnityPlatform *up,
- UnityRect workAreas[],
- uint32 numWorkAreas);
-Bool UnityPlatformSetDesktopConfig(UnityPlatform *up,
- const UnityVirtualDesktopArray *desktops);
-Bool UnityPlatformSetInitialDesktop(UnityPlatform *up,
- UnityDesktopId desktopId);
-Bool UnityPlatformSetDesktopActive(UnityPlatform *up,
- UnityDesktopId desktopId);
-Bool UnityPlatformSetWindowDesktop(UnityPlatform *up,
- UnityWindowId windowId,
- UnityDesktopId desktopId);
-Bool UnityPlatformStickWindow(UnityPlatform *up,
- UnityWindowId windowId);
-Bool UnityPlatformUnstickWindow(UnityPlatform *up,
- UnityWindowId windowId);
-void UnityPlatformSetInterlockMinimizeOperation(UnityPlatform *up,Bool enabled);
-Bool UnityPlatformConfirmMinimizeOperation(UnityPlatform *up,
- UnityWindowId windowId,
- uint32 sequence,
- Bool allow);
-Bool UnityPlatformIsUnityRunning(UnityPlatform *up);
-void UnityPlatformUnlock(UnityPlatform *up);
-void UnityPlatformLock(UnityPlatform *up);
-void UnityPlatformUpdateDnDDetWnd(UnityPlatform *up,
- Bool show);
-void UnityPlatformSetActiveDnDDetWnd(UnityPlatform *up, UnityDnD *detWnd);
-
-void UnityPlatformDoUpdate(UnityPlatform *up, Bool incremental);
-
-void UnityPlatformSetConfigDesktopColor(UnityPlatform *up, int desktopColor);
-
-Bool UnityPlatformRequestWindowContents(UnityPlatform *up,
- UnityWindowId windowIds[],
- uint32 numWindowIds);
-
-Bool UnityPlatformSendMouseWheel(UnityPlatform *up,
- int32 deltaX,
- int32 deltaY,
- int32 deltaZ,
- uint32 modifierFlags);
-void UnityPlatformSetDisableCompositing(UnityPlatform *up, Bool disabled);
-
-#ifdef __cplusplus
-};
-#endif // __cplusplus
-
-#endif // _UNITYPLATFORM_H_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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 util.cc
- *
- * This file just adds some random X utility functions.
- */
-
-#include "x11Platform.h"
-
-
-/*
- ******************************************************************************
- * UnityX11Util_IsWindowDecorationWidget -- */ /**
- *
- * Determine if this window's role is "decoration widget".
- *
- * @param[in] up UnityPlatform context.
- * @param[in] operand Window ID to search for.
- *
- * @todo Use reference counting and toplevel vs. client window distinctions
- * to determine whether this window is relevant to the host-guest window
- * tracker. That's to say that when this window's parent/frame is eventually
- * associated with a client window, we know that this window is no longer
- * a candidate for becoming the client, and that we may stop paying attention
- * to it.
- *
- * @retval TRUE Window is a decoration widget.
- * @retval FALSE Window is not a decoration widget.
- *
- ******************************************************************************
- */
-
-Bool
-UnityX11Util_IsWindowDecorationWidget(UnityPlatform *up,
- Window w)
-{
- Atom propertyType;
- int propertyFormat;
- unsigned long bytesReturned = 0;
- unsigned long bytesRemaining;
- char *valueReturned = NULL;
- Bool retval = FALSE;
-
- if (XGetWindowProperty(up->display, w, up->atoms.WM_WINDOW_ROLE, 0, 1024,
- False, AnyPropertyType, &propertyType,
- &propertyFormat, &bytesReturned, &bytesRemaining,
- (unsigned char **) &valueReturned)
- == Success
- && bytesReturned > 0
- && propertyType == XA_STRING
- && propertyFormat == 8
- && strcmp(valueReturned, "decoration widget") == 0) {
- retval = TRUE;
- }
-
- XFree(valueReturned);
-
- UnityPlatformResetErrorCount(up);
- return retval;
-}
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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.
- *
- *********************************************************/
-
-/*
- * windowPathFactory.hh --
- *
- * Factory class which, given an X window ID, PID, or pathname tries to
- * find executable path and its corresponding "desktop entry" file. (See
- * http://standards.freedesktop.org/desktop-entry-spec/latest/.)
- */
-
-#ifndef _UNITY_WINDOWPATHFACTORY_HH_
-#define _UNITY_WINDOWPATHFACTORY_HH_
-
-#include <tr1/unordered_map>
-#include <glibmm.h>
-#include <utility>
-#include <vector>
-
-extern "C" {
-#include <X11/Xlib.h>
-}
-
-namespace Glib {
- class ustring;
-}
-
-namespace vmware {
-namespace tools {
-namespace unity {
-
-class WindowPathFactory {
-public:
- // executable path, desktop entry path
- typedef std::pair<Glib::ustring, Glib::ustring> WindowPathPair;
-
- WindowPathFactory(Display* dpy);
- bool FindByXid(XID window, WindowPathPair& pathPair);
-
-private:
- typedef std::tr1::unordered_map<Glib::ustring, WindowPathPair,
- std::tr1::hash<std::string> > ExecMap;
- typedef std::pair<Glib::RefPtr<Glib::Regex>, std::string> ExecPattern;
-
- Glib::ustring CanonicalizeAppName(const Glib::ustring& appName,
- const Glib::ustring& cwd);
- bool FindByArgv(const Glib::ustring& cwd, std::vector<Glib::ustring> argv,
- WindowPathPair& pathPair);
- bool FindByPid(pid_t pid, WindowPathPair& pathPair);
- pid_t GetPidForXid(XID window);
- bool IsSkippable(const Glib::ustring& component);
- Window LookupClientLeader(XID window);
-
- Display* mDpy;
- ExecMap mExecMap;
- std::vector<std::string> mEnvPrefixes;
- std::vector<ExecPattern> mExecPatterns;
- Glib::RefPtr<Glib::Regex> mSkipPatterns;
-};
-
-} /* namespace unity */ } /* namespace tools */ } /* namespace vmware */
-
-
-#endif // ifndef _UNITY_WINDOWPATHFACTORY_HH_
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007-2010 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.
- *
- *********************************************************/
-
-/*
- * window.cc --
- *
- * Implementation of Unity for guest operating systems that use the X11 windowing
- * system. This file implements per-window operations (move, minimize, etc.)
- */
-
-#include "x11Platform.h"
-extern "C" {
-#include "base64.h"
-#include "region.h"
-#include "imageUtil.h"
-#include <time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-}
-
-#include "Uri.h"
-#include "appUtil.h"
-#include "ghIntegration.h"
-
-using vmware::tools::unity::WindowPathFactory;
-
-/*
- * Utility routines
- */
-static Bool UnityPlatformFindWindows(UnityPlatform *up,
- Window currentWindow,
- Window *toplevelWindow,
- Window *clientWindow,
- Window *rootWindow);
-static Bool UPWindowPushFullUpdate(UnityPlatform *up, UnityPlatformWindow *upw);
-static void UPWindowSetRelevance(UnityPlatform *up,
- UnityPlatformWindow *upw,
- Bool isRelevant);
-static void UPWindowUpdateActions(UnityPlatform *up, UnityPlatformWindow *upw);
-static void UPWindowUpdateDesktop(UnityPlatform *up, UnityPlatformWindow *upw);
-static void UPWindowUpdateIcon(UnityPlatform *up, UnityPlatformWindow *upw);
-static void UPWindowUpdateProtocols(UnityPlatform *up, UnityPlatformWindow *upw);
-#if defined(VM_HAVE_X11_SHAPE_EXT)
-static void UPWindowUpdateShape(UnityPlatform *up, UnityPlatformWindow *upw);
-#endif
-static void UPWindowUpdateState(UnityPlatform *up,
- UnityPlatformWindow *upw,
- const XPropertyEvent *xevent);
-static void UPWindowUpdateTitle(UnityPlatform *up, UnityPlatformWindow *upw);
-static void UPWindowUpdateType(UnityPlatform *up, UnityPlatformWindow *upw);
-static void UPWindowProcessConfigureEvent(UnityPlatform *up,
- UnityPlatformWindow *upw,
- const XEvent *xevent);
-static void UPWindowProcessPropertyEvent(UnityPlatform *up,
- UnityPlatformWindow *upw,
- const XEvent *xevent);
-static void UPWindowProcessShapeEvent(UnityPlatform *up,
- UnityPlatformWindow *upw,
- const XEvent *xevent);
-static Bool UPWindowGetDesktop(UnityPlatform *up,
- UnityPlatformWindow *upw,
- int *guestDesktop);
-static void UPWindowSetWindows(UnityPlatform *up,
- UnityPlatformWindow *upw,
- Window toplevelWindow,
- Window clientWindow);
-static void UPWindowUpdateFrameExtents(UnityPlatform *up,
- UnityPlatformWindow *upw);
-
-
-#ifdef VMX86_DEVEL
-/*
- *-----------------------------------------------------------------------------
- *
- * CompareStackingOrder --
- *
- * Very crudely compares the stacking orders of "relevant" windows as kept
- * by the X server and ourselves. (By relevant, we mean only windows which
- * are relayed to the window tracker.)
- *
- * If there's a mismatch, Debug() statements are generated showing which
- * indices do not match and the corresponding window IDs. If there is a match,
- * then the current stacking order is displayed. (The latter is useless on
- * its own, but it's a handy bit of data to refer to when a mismatch is
- * discovered.)
- *
- * Results:
- * Additional noise is sent to the Tools log via Debug().
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-CompareStackingOrder(UnityPlatform *up, // IN
- Window rootWindow, // IN
- const char *callerName) // IN
-{
- Window *relevantUChildren = NULL;
- Window *relevantXChildren = NULL;
- Window *trackerChildren = NULL;
- unsigned int i;
- unsigned int numXRelevant; // relevant windows from the X server
- unsigned int numURelevant; // relevant windows according to Unity
- unsigned int nWindows; // Generic limit referring to all of *children variables
- // after we determine that they are all the same
- // size. Likely that it will be optimized out.
- GList *unityList = NULL;
-
- /*
- * First query the X server for a list of its top-level windows sorted
- * from bottom to top stacking order.
- */
- {
- Window dummyroot;
- Window dummyparent;
- Window *children = NULL;
- unsigned int nchildren;
-
- if (!XQueryTree(up->display, rootWindow, &dummyroot, &dummyparent,
- &children, &nchildren)) {
- Debug("%s: XQueryTree failed\n", __func__);
- goto out;
- }
-
- /*
- * Now, filter out all of the relevant top-level windows into a local buffer
- * from the stack.
- */
- relevantXChildren = g_new(Window, nchildren);
-
- for (i = 0, numXRelevant = 0; i < nchildren; i++) {
- UnityPlatformWindow *tmpupw;
- tmpupw = UPWindow_Lookup(up, children[i]);
- if (tmpupw && tmpupw->isRelevant) {
- relevantXChildren[numXRelevant++] = children[i];
- }
- }
-
- XFree(children);
- }
-
- /*
- * Do the same as above but for the windows known to Unity. These lists should
- * -usually- match, but may get out of sync when a window disappears, for example.
- * However, it's also -usually- only a matter of time before subsequent events show
- * up and bring them back into sync.
- *
- * Note that this list is created by -prepending- windows. This is done because
- * while we store windows in top-bottom stacking order, the X server maintains
- * windows in bottom-top stacking order. For ease of comparison, I'm reversing
- * our order in order to match the X server.
- */
- {
- UnityPlatformWindow *myupw;
- for (myupw = up->topWindow, numURelevant = 0;
- myupw;
- myupw = myupw->lowerWindow) {
- if (myupw->isRelevant) {
- unityList = g_list_prepend(unityList, (gpointer)myupw->toplevelWindow);
- ++numURelevant;
- }
- }
- }
-
- /*
- * The following check ensures that all three window collections are the same
- * size. With that in mind, for the sake of readability I'll use a variable,
- * nWindows, to refer to this common size through the remainer of the function.
- */
- if (numURelevant != numXRelevant ||
- numURelevant != up->tracker->count) {
- Debug("%s: mismatch (count): server %u, unity %u, uwt %u\n", __func__,
- numXRelevant, numURelevant, up->tracker->count);
- goto out;
- }
-
- nWindows = numURelevant;
-
- /*
- * We're now sure that all sets of windows to be compared are the same size.
- * Go ahead and allocate and populate new arrays for window set comparisons.
- */
-
- relevantUChildren = g_new(Window, nWindows);
- trackerChildren = g_new(Window, nWindows);
-
- /*
- * Convert the now sorted (see above re: g_list_prepend) Unity window list to
- * an array for easy comparison with * the X server's array.
- */
- {
- GList *listIter;
- for (listIter = unityList, i = 0;
- listIter;
- listIter = listIter->next, i++) {
- relevantUChildren[i] = (Window)listIter->data;
- }
- }
-
- /*
- * Once again, UWT stores windows in top-bottom stacking order, but we're
- * comparing an array in bottom-top stacking order. This loop just copies
- * and reverses the UWT's zorder array.
- */
- for (i = 0; i < nWindows; i++) {
- trackerChildren[i] = up->tracker->zorder[(nWindows - 1) - i];
- }
-
- {
- size_t childrenSize = nWindows * sizeof *relevantUChildren;
-
- if (memcmp(relevantXChildren, relevantUChildren, childrenSize) ||
- memcmp(relevantXChildren, trackerChildren, childrenSize)) {
- Debug("%s: mismatch!\n", callerName);
- Debug("%s: %8s %10s %10s %10s\n", callerName, "index", "X Server",
- "Unity", "UWT");
-
- for (i = 0; i < nWindows; i++) {
- if (relevantXChildren[i] != relevantUChildren[i] ||
- relevantXChildren[i] != trackerChildren[i]) {
- Debug("%s: [%6u] %#10lx %#10lx %#10lx\n", callerName, i,
- relevantXChildren[i], relevantUChildren[i],
- trackerChildren[i]);
- }
- }
- } else {
- Debug("%s: match (%u windows).\n", callerName, nWindows);
- for (i = 0; i < nWindows; i++) {
- Debug("%s: [%u] %#lx\n", callerName, i, relevantXChildren[i]);
- }
- }
- }
-
-out:
- g_free(relevantXChildren);
- g_free(relevantUChildren);
- g_free(trackerChildren);
- g_list_free(unityList);
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformFindClientWindow --
- *
- * In X, the immediate children of the root window are almost always window manager
- * windows that hold the app's windows. Sometimes we want to find the actual app's
- * window to operate on, usually identfied by the WM_STATE property. Given a random
- * window ID, this function figures out which is which.
- *
- * Results:
- * TRUE if successful, FALSE otherwise.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-UnityPlatformFindWindows(UnityPlatform *up, // IN
- Window currentWindow, // IN
- Window *toplevelWindow, // OUT
- Window *clientWindow, // OUT
- Window *rootWindow) // OUT
-{
- Bool retval = FALSE;
-
- Window rootWin;
- Window parentWin;
- Window *children = NULL;
- unsigned int numChildren;
-
- Atom propertyType;
- int propertyFormat;
- unsigned long itemsReturned;
- unsigned long bytesRemaining;
- unsigned char *valueReturned = NULL;
-
- ASSERT(up);
- ASSERT(toplevelWindow);
- ASSERT(clientWindow);
- ASSERT(rootWindow);
-
- /* Check for the WM_STATE property on the window */
- UnityPlatformResetErrorCount(up);
- XGetWindowProperty(up->display, (Window)currentWindow, up->atoms.WM_STATE, 0,
- 1024, False, AnyPropertyType,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, &valueReturned);
- XFree(valueReturned);
- if (UnityPlatformGetErrorCount(up)) {
- Debug("Retrieving WM_STATE failed\n");
- return FALSE;
- }
-
- XQueryTree(up->display, currentWindow, &rootWin, &parentWin,
- &children, &numChildren);
- if (UnityPlatformGetErrorCount(up)) {
- Debug("XQueryTree failed\n");
- return FALSE;
- }
-
- if (propertyType != None) {
- /*
- * If WM_STATE exists on this window, we were given a client window
- */
- *clientWindow = currentWindow;
- *rootWindow = rootWin;
-
- XFree(children);
- children = NULL;
-
- /*
- * This loop ensures that parentWin is the direct child of the root.
- *
- * XXX this will break for any window managers that use subwindows to implement
- * virtual desktops.
- */
- while (parentWin != rootWin) {
- currentWindow = parentWin;
-
- XQueryTree(up->display, currentWindow, &rootWin,
- &parentWin, &children, &numChildren);
- XFree(children);
- children = NULL;
- }
- *toplevelWindow = currentWindow;
-
- retval = TRUE;
- } else if (parentWin == rootWin) {
- uint i;
- GQueue *windowQueue;
-
- /*
- * Do a breadth-first search down the window tree to find the child that has the
- * WM_STATE property.
- */
- ASSERT(UnityPlatformIsRootWindow(up, rootWin));
-
- *toplevelWindow = currentWindow;
- *rootWindow = rootWin;
- *clientWindow = None;
-
- windowQueue = g_queue_new();
-
- while (numChildren || !g_queue_is_empty(windowQueue)) {
- Window childWindow;
-
- for (i = 0; i < numChildren; i++) {
- g_queue_push_tail(windowQueue, GUINT_TO_POINTER(children[i]));
- }
- XFree(children);
- children = NULL;
-
- childWindow = GPOINTER_TO_UINT(g_queue_pop_head(windowQueue));
-
- propertyType = None;
- valueReturned = NULL;
- itemsReturned = 0;
- XGetWindowProperty(up->display, childWindow, up->atoms.WM_STATE, 0,
- 1024, False, AnyPropertyType,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, &valueReturned);
- XFree(valueReturned);
-
- if (UnityPlatformGetErrorCount(up)) {
- g_queue_free(windowQueue);
- Debug("Getting WM_STATE on a child failed\n");
- return FALSE;
- }
-
- if (itemsReturned) {
- *clientWindow = childWindow;
- break;
- }
-
- XQueryTree(up->display, childWindow, &rootWin,
- &parentWin, &children, &numChildren);
- if (UnityPlatformGetErrorCount(up)) {
- g_queue_free(windowQueue);
- Debug("XQueryTree failed\n");
- return FALSE;
- }
- }
-
- g_queue_free(windowQueue);
-
- retval = TRUE;
- } /* else, retval is FALSE */
-
- XFree(children);
-
- if (retval && (*toplevelWindow == *rootWindow || *clientWindow == *rootWindow)) {
- Panic("Creating a UnityPlatformWindow of a root window is a big error\n");
- }
-
- return retval;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowSetWindows --
- *
- * Updates the X11 windows that a UnityPlatformWindow represents. Used mainly if a
- * window is created or reparented.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Updates internal Unity state.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowSetWindows(UnityPlatform *up, // IN
- UnityPlatformWindow *upw, // IN
- Window toplevelWindow, // IN
- Window clientWindow) // IN
-{
- UnityPlatformWindow *scratchUpw;
- Bool wasRelevant;
-
- ASSERT(up);
- ASSERT(upw);
-
- wasRelevant = upw->isRelevant;
-
- Debug("%s: %#lx::%#lx -> %#lx::%#lx\n", __func__, upw->toplevelWindow,
- upw->clientWindow, toplevelWindow, clientWindow);
- UPWindowSetRelevance(up, upw, FALSE);
- if (upw->toplevelWindow) {
- XSelectInput(up->display, upw->toplevelWindow, 0);
- HashTable_Delete(up->allWindows, GUINT_TO_POINTER(upw->toplevelWindow));
- }
- if (upw->clientWindow) {
- XSelectInput(up->display, upw->clientWindow, 0);
- HashTable_Delete(up->allWindows, GUINT_TO_POINTER(upw->clientWindow));
- }
-#if defined(VM_HAVE_X11_SHAPE_EXT)
- if (up->shapeEventBase) {
- XShapeSelectInput(up->display, upw->toplevelWindow, 0);
-
- if (upw->clientWindow) {
- XShapeSelectInput(up->display, upw->clientWindow, 0);
- }
- }
-#endif
-
- /*
- * Okay, now we may have two UnityPlatformWindows running around, one each for
- * the top-level and client windows in response to their CreateNotify events,
- * and this routine wishes to unify both in a single UPW.
- *
- * XXX The current course of action is this:
- * 1. If either our operand top-level or client windows belong to
- * any other UnityPlatformWindows, said UPWs will be dereferenced.
- * 2. We'll then assign the operand windows to the current UPW.
- */
- scratchUpw = UPWindow_Lookup(up, toplevelWindow);
- if (scratchUpw && scratchUpw != upw) {
- UPWindow_Unref(up, scratchUpw);
- }
- scratchUpw = UPWindow_Lookup(up, clientWindow);
- if (scratchUpw && scratchUpw != upw) {
- UPWindow_Unref(up, scratchUpw);
- }
-
- upw->toplevelWindow = toplevelWindow;
- upw->clientWindow = clientWindow;
-
- /*
- * Start listening to events on this window. We want these even if the window is of no
- * interest to us, because the specified events may make the window interesting to us.
- */
- if (clientWindow) {
- XSelectInput(up->display, clientWindow, PropertyChangeMask | StructureNotifyMask);
- }
-
- XSelectInput(up->display,
- toplevelWindow,
- FocusChangeMask | PropertyChangeMask | StructureNotifyMask);
-
-#if defined(VM_HAVE_X11_SHAPE_EXT)
- if (up->shapeEventBase) {
- XShapeSelectInput(up->display, toplevelWindow, ShapeNotifyMask);
-
- if (upw->clientWindow) {
- XShapeSelectInput(up->display, upw->clientWindow, ShapeNotifyMask);
- }
- }
-#endif
-
- HashTable_Insert(up->allWindows, GUINT_TO_POINTER(upw->toplevelWindow), upw);
- if (upw->clientWindow) {
- HashTable_Insert(up->allWindows, GUINT_TO_POINTER(upw->clientWindow), upw);
- }
- UPWindowSetRelevance(up, upw, wasRelevant);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindow_Create --
- *
- * Creates a UnityPlatformWindow for the specified UnityWindowId. The resulting
- * object will have a reference count of 1 that is owned by the caller.
- *
- * Results:
- * The newly created UnityPlatformWindow.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-UnityPlatformWindow *
-UPWindow_Create(UnityPlatform *up, // IN
- Window window) // IN
-{
- UnityPlatformWindow *upw;
- Window toplevelWindow;
- Window clientWindow;
- Window rootWindow;
-
- ASSERT(up);
- ASSERT(window != None);
-
- if (!UnityPlatformFindWindows(up, window,
- &toplevelWindow, &clientWindow, &rootWindow)) {
- Debug("FindWindows failed on %#lx\n", window);
- return NULL;
- }
-
- if (HashTable_Lookup(up->allWindows,
- GUINT_TO_POINTER(toplevelWindow),
- (void **)&upw)) {
- Debug("Lookup of window %#lx returned %#lx\n",
- toplevelWindow, upw->toplevelWindow);
- abort();
- }
-
- if (HashTable_Lookup(up->allWindows,
- GUINT_TO_POINTER(clientWindow),
- (void **)&upw)) {
- Debug("Lookup of clientWindow %#lx returned existing toplevel %#lx\n",
- clientWindow, upw->toplevelWindow);
- return NULL;
- }
-
- upw = (UnityPlatformWindow*)Util_SafeCalloc(1, sizeof *upw);
- upw->refs = 1;
-
- Debug("Creating new window for %#lx/%#lx/%#lx\n",
- toplevelWindow, clientWindow, rootWindow);
- upw->rootWindow = rootWindow;
- for (upw->screenNumber = 0;
- upw->screenNumber < (int)up->rootWindows->numWindows
- && up->rootWindows->windows[upw->screenNumber] != rootWindow;
- upw->screenNumber++);
- DynBuf_Init(&upw->iconPng.data);
- DynBuf_SetSize(&upw->iconPng.data, 0);
-
- UPWindowSetWindows(up, upw, toplevelWindow, clientWindow);
-
- /*
- * Put newly created windows on the top of the stack by default.
- */
- upw->higherWindow = NULL;
- upw->lowerWindow = up->topWindow;
- if (upw->lowerWindow) {
- upw->lowerWindow->higherWindow = upw;
- }
- up->topWindow = upw;
-
- return upw;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindow_Ref --
- *
- * Increases the reference count on the UnityPlatformWindow object by one.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UPWindow_Ref(UnityPlatform *up, // IN
- UnityPlatformWindow *upw) // IN
-{
- upw->refs++;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindow_Unref --
- *
- * Decreases the reference count on the UnityPlatformWindow object by one.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May destroy the object if no references remain.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UPWindow_Unref(UnityPlatform *up, // IN
- UnityPlatformWindow *upw) // IN
-{
- upw->refs--;
-
- if (upw->refs <= 0) { // Window needs destroying
- UPWindowSetRelevance(up, upw, FALSE);
-
- /*
- * Filter out windows that have been already destroyed on the X11 side, but which
- * still may have had refcounts active.
- */
- if (upw->windowType != UNITY_WINDOW_TYPE_NONE) {
- XSelectInput(up->display, upw->toplevelWindow, 0);
-
-#if defined(VM_HAVE_X11_SHAPE_EXT)
- if (up->shapeEventBase) {
- XShapeSelectInput(up->display, upw->toplevelWindow, 0);
- }
-#endif
-
- if (upw->clientWindow) {
- XSelectInput(up->display, upw->clientWindow, 0);
- }
- }
-
- HashTable_Delete(up->allWindows, GUINT_TO_POINTER(upw->toplevelWindow));
- if (upw->clientWindow) {
- HashTable_Delete(up->allWindows, GUINT_TO_POINTER(upw->clientWindow));
- }
-
- DynBuf_Destroy(&upw->iconPng.data);
-
- if (upw->higherWindow) {
- upw->higherWindow->lowerWindow = upw->lowerWindow;
- }
- if (upw->lowerWindow) {
- upw->lowerWindow->higherWindow = upw->higherWindow;
- }
- if (upw == up->topWindow) {
- up->topWindow = upw->lowerWindow;
- }
-
- free(upw);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindow_Lookup --
- *
- * Retrieves the UnityPlatformWindow object associated with a given Window ID
- *
- * Results:
- * The UnityPlatformWindow object, or NULL if it was not found
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-UnityPlatformWindow *
-UPWindow_Lookup(UnityPlatform *up, // IN
- Window window) // IN
-{
- UnityPlatformWindow *retval = NULL;
-
- HashTable_Lookup(up->allWindows, GUINT_TO_POINTER(window), (void **)&retval);
-
- return retval;
-}
-
-#if 0 // Very useful if ever debugging the window stacking code, but slow otherwise.
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowCheckStack --
- *
- * Sanity check on the linked list of windows for Z-ordering.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May ASSERT() if things are broken.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowCheckStack(UnityPlatform *up)
-{
- UnityPlatformWindow **upwList;
- size_t numWindows;
- size_t i;
- UnityPlatformWindow *curWindow;
-
- HashTable_ToArray(up->allWindows,
- (void ***)&upwList,
- &numWindows);
- for (i = 0; i < numWindows; i++) {
- for (curWindow = up->topWindow;
- curWindow;
- curWindow = curWindow->lowerWindow) {
- if (curWindow == upwList[i]) {
- break;
- }
- }
-
- if (curWindow != upwList[i]) {
- Debug("%s: Wanted %p. Complete window stack is: ", __FUNCTION__, upwList[i]);
- for (curWindow = up->topWindow;
- curWindow;
- curWindow = curWindow->lowerWindow) {
- if (curWindow == upwList[i]) {
- Debug("%p ->", curWindow);
- } else {
- Debug("[%p] ->", curWindow);
- }
- }
- Debug("NULL\n");
-
- Debug("%s: Window stack downwards from %p: ", __FUNCTION__, upwList[i]);
- for (curWindow = upwList[i];
- curWindow;
- curWindow = curWindow->lowerWindow) {
- if (curWindow == upwList[i]) {
- Debug("[%p] ->", curWindow);
- } else {
- Debug("%p ->", curWindow);
- }
- }
- Debug("NULL\n");
-
- Debug("%s: Window stack upwards from %p: ", __FUNCTION__, upwList[i]);
- for (curWindow = upwList[i];
- curWindow;
- curWindow = curWindow->higherWindow) {
- if (curWindow == upwList[i]) {
- Debug("[%p] <-", curWindow);
- } else {
- Debug("%p <-", curWindow);
- }
- }
- Debug("NULL\n");
- }
-
- ASSERT(curWindow == upwList[i]);
- }
- for (curWindow = up->topWindow;
- curWindow;
- curWindow = curWindow->lowerWindow) {
- for (i = 0; i < numWindows; i++) {
- if (curWindow == upwList[i]) {
- break;
- }
- }
- ASSERT(i < numWindows);
- }
-
- free(upwList);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowCheckCycle --
- *
- * Checks to make sure there are no loops in the window stack.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May ASSERT().
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowCheckCycle(UnityPlatform *up)
-{
- UnityPlatformWindow *upw;
- UnityPlatformWindow *curWindow;
-
- for (upw = up->topWindow; upw; upw = upw->lowerWindow) {
- for (curWindow = upw->lowerWindow; curWindow; curWindow = curWindow->lowerWindow) {
- ASSERT(curWindow != upw);
- }
- }
-
- for (upw = up->topWindow; upw->lowerWindow; upw = upw->lowerWindow) {
- /* Find lowest window */
- }
-
- for (; upw; upw = upw->higherWindow) {
- for (curWindow = upw->higherWindow; curWindow; curWindow = curWindow->higherWindow) {
- ASSERT(curWindow != upw);
- }
- }
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindow_Restack --
- *
- * Changes the Z order list of the specified window so it is
- * immediately above another window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Updates UnityWindowTracker with the latest ZOrder.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UPWindow_Restack(UnityPlatform *up, // IN
- UnityPlatformWindow *upw, // IN
- Window above) // IN - None indicates stack at bottom
-{
- UnityPlatformWindow *newLowerWindow = NULL;
-
- ASSERT(up);
- ASSERT(upw);
-
- if (above != None) {
- newLowerWindow = UPWindow_Lookup(up, above);
-
- if (!newLowerWindow) {
- if (upw != up->topWindow) {
- Debug("%s: Couldn't find the window to stack above [%#lx].\n",
- __func__, above);
- return;
- } else {
- return;
- }
- }
- }
- ASSERT(newLowerWindow != upw);
-
- if (newLowerWindow != upw->lowerWindow) {
- /*
- * Stacking order has changed. Move this window to the right place in the stack.
- *
- * 1. Remove 'upw' from the old location in the linked list.
- * 2. Find the 'upw' that it is now above.
- * 3. Insert it into the right location in the list.
- */
-
- ASSERT(upw->higherWindow != upw);
- ASSERT(upw->lowerWindow != upw);
- if (upw->higherWindow) {
- upw->higherWindow->lowerWindow = upw->lowerWindow;
- } else {
- up->topWindow = upw->lowerWindow;
- }
-
- ASSERT(upw->higherWindow != upw);
- ASSERT(upw->lowerWindow != upw);
- if (upw->lowerWindow) {
- upw->lowerWindow->higherWindow = upw->higherWindow;
- }
- upw->higherWindow = NULL;
- upw->lowerWindow = NULL;
-
- ASSERT(upw->higherWindow != upw);
- ASSERT(upw->lowerWindow != upw);
- upw->lowerWindow = newLowerWindow;
- if (newLowerWindow) {
- upw->higherWindow = newLowerWindow->higherWindow;
- upw->lowerWindow->higherWindow = upw;
- ASSERT(newLowerWindow != upw);
- } else {
- /*
- * This window is meant to go to the bottom of the stack.
- */
- upw->lowerWindow = NULL;
- upw->higherWindow = up->topWindow;
-
- while (upw->higherWindow && upw->higherWindow->lowerWindow) {
- upw->higherWindow = upw->higherWindow->lowerWindow;
- }
- ASSERT(newLowerWindow != upw);
- }
-
- ASSERT(newLowerWindow != upw);
- ASSERT(upw->higherWindow != upw);
- ASSERT(upw->lowerWindow != upw);
- if (upw->higherWindow) {
- ASSERT(upw->higherWindow->lowerWindow == newLowerWindow);
- upw->higherWindow->lowerWindow = upw;
- } else {
- up->topWindow = upw;
- }
-
- ASSERT(upw->higherWindow != upw);
- ASSERT(upw->lowerWindow != upw);
- if (upw->isRelevant) {
- up->stackingChanged = TRUE;
- Debug("Stacking order has changed\n");
- }
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowSetRelevance --
- *
- * Changes the "relevance" of a particular window. Normally, the decision of whether
- * to do this should be made only by CheckRelevance().
- *
- * Results:
- * None.
- *
- * Side effects:
- * May add or remove the window in UnityWindowTracker.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowSetRelevance(UnityPlatform *up, // IN
- UnityPlatformWindow *upw, // IN
- Bool isRelevant) // IN
-{
- if ((isRelevant && upw->isRelevant) || (!isRelevant && !upw->isRelevant)) {
- return;
- }
-
- upw->isRelevant = isRelevant;
- if (isRelevant) {
- DynBuf windowPath;
- DynBuf execPath;
-
- DynBuf_Init(&windowPath);
- DynBuf_Init(&execPath);
-
- if (upw->windowType == UNITY_WINDOW_TYPE_NORMAL) {
- Bool retval;
- retval = UnityPlatformGetWindowPath(up,
- upw->toplevelWindow,
- &windowPath,
- &execPath);
- if (!retval) {
- Debug("GetWindowPath didn't know how to identify the window...\n");
- }
- }
-
- Debug("Adding window %#lx to tracker\n", upw->toplevelWindow);
- UnityWindowTracker_AddWindowWithData(up->tracker,
- upw->toplevelWindow,
- &windowPath,
- &execPath,
- upw);
- DynBuf_Destroy(&windowPath);
- DynBuf_Destroy(&execPath);
-
- UPWindowPushFullUpdate(up, upw);
- } else {
- Debug("Removing window %#lx from tracker\n", upw->toplevelWindow);
- UnityWindowTracker_RemoveWindow(up->tracker, upw->toplevelWindow);
- UnityPlatformDoUpdate(up, TRUE);
- }
-
- up->stackingChanged = TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindow_CheckRelevance --
- *
- * Looks at the current state of a window to figure out whether we want to relay it
- * through UnityWindowTracker.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Updates various cached metadata in UnityPlatformWindow, such as windowType and
- * isOverrideRedirect.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UPWindow_CheckRelevance(UnityPlatform *up, // IN
- UnityPlatformWindow *upw, // IN
- const XEvent *motivator) // IN - optional
-{
- XWindowAttributes winAttr;
- int shouldBeRelevant = -1;
- Bool regetDesktop = FALSE;
-
- if (motivator) {
- /*
- * We have an event that may have modified the relevance of this window. See what
- * we need to do.
- */
- switch (motivator->type) {
- case PropertyNotify:
- {
- XPropertyEvent *event = (XPropertyEvent *)motivator;
- if (upw->waitingForWmState &&
- event->atom == up->atoms.WM_STATE &&
- event->state == PropertyNewValue) {
- Window toplevelWindow = 0;
- Window clientWindow = 0;
- Window rootWindow = 0;
- Bool success;
-
- regetDesktop = TRUE;
- Debug("%s: PropertyNotify: New WM_STATE on %#lx (current upw: %#lx::%#lx)\n",
- __func__, event->window, upw->toplevelWindow, upw->clientWindow);
- success = UnityPlatformFindWindows(up, event->window,
- &toplevelWindow, &clientWindow,
- &rootWindow);
- if (success) {
- UPWindowSetWindows(up, upw, toplevelWindow, clientWindow);
- upw->waitingForWmState = FALSE;
- Debug("%s: PropertyNotify: new upw: %#lx::%#lx\n",
- __func__, upw->toplevelWindow, upw->clientWindow);
- } else {
- Debug("%s: PropertyNotify: FindWindows failed again!\n", __func__);
- return;
- }
- } else if (event->atom == up->atoms.WM_WINDOW_ROLE &&
- event->state == PropertyNewValue &&
- UnityX11Util_IsWindowDecorationWidget(up, upw->toplevelWindow)) {
- Debug("%s: Window %#lx is a decoration widget. Ignore it.\n",
- __func__, upw->toplevelWindow);
- upw->deleteWhenSafe = TRUE;
- return;
- } else if (event->atom == up->atoms._NET_WM_DESKTOP) {
- if (upw->wantSetDesktopNumberOnUnmap) {
- /*
- * We're to preserve _NET_WM_DESKTOP across unmapping and remapping a
- * window (most likely a taskbar). If we see PropertyDelete, assume
- * it's ours and reset the _NET_WM_DESKTOP property. If, however, we
- * instead see a PropertyNewValue (the only other possibility, hence
- * no "else" below), then we assume some other client wished to change
- * the property, and we forget about restoring _NET_WM_DESKTOP when
- * we remap the window later.
- */
- if (event->state == PropertyDelete) {
- Debug("%s: PropertyDelete: _NET_WM_DESKTOP: %#lx. Resetting to %d.\n",
- __func__, upw->clientWindow, upw->onUnmapDesktopNumber);
- UPWindow_SetEWMHDesktop(up, upw, upw->onUnmapDesktopNumber);
- }
- upw->wantSetDesktopNumberOnUnmap = FALSE;
- return;
- }
- regetDesktop = TRUE;
- } else if (event->atom != up->atoms._NET_WM_WINDOW_TYPE) {
- return;
- }
- }
- break;
-
- case ConfigureNotify:
- if ((motivator->xconfigure.override_redirect ? TRUE : FALSE)
- == upw->isOverrideRedirect) {
- return;
- }
- break;
-
- case UnmapNotify:
- /*
- * XXX should we ignore UnmapNotify events if they come from non-override
- * redirect windows?
- */
-
- /*
- * If a window is override redirect (e.g. tooltips), then we may need to show
- * & hide it based on map & unmap, because we won't get WM_STATE updates to
- * help us do minimize/restore.
- */
- break;
-
- case MapNotify:
- if (upw->wantSetDesktopNumberOnUnmap) {
- Debug("%s: Expected PropertyDelete before MapNotify.\n", __func__);
- upw->wantSetDesktopNumberOnUnmap = FALSE;
- }
- regetDesktop = TRUE;
- break;
-
- case ReparentNotify:
- {
- Window toplevelWindow = 0;
- Window clientWindow = 0;
- Window rootWindow = 0;
- const XReparentEvent *reparent = &motivator->xreparent;
- Bool success;
-
- regetDesktop = TRUE;
- Debug("%s: ReparentNotify: %#lx reparented to %#lx (current upw: %#lx::%#lx)\n",
- __func__, reparent->window, reparent->parent,
- upw->toplevelWindow, upw->clientWindow);
- success = UnityPlatformFindWindows(up, reparent->window,
- &toplevelWindow, &clientWindow,
- &rootWindow);
- if (success) {
- UPWindowSetWindows(up, upw, toplevelWindow, clientWindow);
- } else {
- Debug("%s: ReparentNotify: UnityPlatformFindWindows failed."
- " Waiting for WM_STATE.\n", __func__);
- upw->waitingForWmState = TRUE;
- return;
- }
- }
- break;
-
- case DestroyNotify:
- shouldBeRelevant = FALSE;
- break;
-
- default:
- return;
- }
- } else {
- regetDesktop = TRUE;
- }
-
- if (shouldBeRelevant == -1) {
- Bool onCurrentDesktop = TRUE;
- Bool isInvisible = FALSE;
- Bool ignoreThisWindow = FALSE;
-
- UnityPlatformResetErrorCount(up);
-
- XGetWindowAttributes(up->display, upw->toplevelWindow, &winAttr);
- if (UnityPlatformGetErrorCount(up)) {
- shouldBeRelevant = FALSE;
- goto out;
- }
-
- if (regetDesktop) {
- if (!UPWindowGetDesktop(up, upw, &upw->desktopNumber)) {
- upw->desktopNumber = -1;
- } else {
- if (upw->wantSetDesktopNumberOnUnmap) {
- upw->onUnmapDesktopNumber = upw->desktopNumber;
- }
- }
- }
- if (upw->desktopNumber < (int)up->desktopInfo.numDesktops
- && upw->desktopNumber >= 0
- && up->desktopInfo.guestDesktopToUnity[upw->desktopNumber] !=
- UnityWindowTracker_GetActiveDesktop(up->tracker)) {
- onCurrentDesktop = FALSE;
- }
- upw->isViewable = (winAttr.map_state == IsViewable);
- if (!upw->wasViewable) {
- if (upw->isViewable) {
- upw->wasViewable = upw->isViewable;
- } else {
- /*
- * Check if it's in iconic state (i.e. minimized), which means it was viewable
- * previously as far as we're concerned.
- */
-
- Atom propertyType;
- int propertyFormat;
- unsigned long itemsReturned = 0;
- unsigned long bytesRemaining;
- Atom *valueReturned = NULL;
- Window mainWindow = upw->clientWindow ? upw->clientWindow : upw->toplevelWindow;
-
- if (XGetWindowProperty(up->display, mainWindow, up->atoms.WM_STATE, 0,
- 1024, False, AnyPropertyType,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, (unsigned char **) &valueReturned)
- == Success
- && itemsReturned > 0
- && propertyType == up->atoms.WM_STATE
- && propertyFormat == 32
- && valueReturned[0] == IconicState) {
- upw->wasViewable = TRUE;
- Debug("Found window %#lx/%#lx initially in iconic state\n",
- upw->toplevelWindow, upw->clientWindow);
- } else {
- upw->wasViewable = FALSE;
- }
-
- XFree(valueReturned);
- }
- }
- upw->isOverrideRedirect = winAttr.override_redirect ? TRUE : FALSE;
-
- /*
- * More crazy tests to determine whether a window should be added to the window
- * tracker.
- */
-
- if (winAttr.c_class == InputOnly) {
- /* This is intrinsically true. */
- isInvisible = TRUE;
- } else if (!upw->isViewable && onCurrentDesktop && !upw->clientWindow) {
- /*
- * Evaluate the map state. There are reasons why we'd like to keep unmapped
- * windows in the tracker.
- *
- * 1. The window may be on another desktop.
- * 2. The window may be minimized.
- *
- * upw->clientWindow == None implies that there is no window in the hierarchy
- * with a WM_STATE property. No WM_STATE property means that the window can't
- * be "minimized".
- *
- * I'm using these implications because it saves me from having to explicitly
- * query for/examine WM_STATE here.
- */
- isInvisible = TRUE;
- } else if (winAttr.width <= 1 && winAttr.height <= 1) {
- isInvisible = TRUE;
- } else if ((winAttr.x + winAttr.width) < 0
- || (winAttr.y + winAttr.height) < 0) {
- /*
- * XXX This isn't clear to me. What if winAttr.x > parent's width?
- */
- isInvisible = TRUE;
- }
-
- if (!isInvisible) {
- char *wmname = NULL;
-
- /*
- **************************************
- * This section should hold all the ugly app-specific filtering that might be
- * needed for UnityX11.
- */
-
- if (XFetchName(up->display,
- upw->clientWindow ? upw->clientWindow : upw->toplevelWindow,
- &wmname) != 0) {
- if (!strcmp(wmname, "gksu")
- && winAttr.override_redirect) {
- ignoreThisWindow = TRUE;
- }
-
- XFree(wmname);
- }
-
- /*
- * End app-specific filtering.
- *******************************************
- */
- }
-
- if (isInvisible) {
- shouldBeRelevant = FALSE;
- } else if (ignoreThisWindow) {
- shouldBeRelevant = FALSE;
- } else {
- Atom netWmWindowType = up->atoms._NET_WM_WINDOW_TYPE_NORMAL;
- Atom netWmPropertyType;
- int netWmPropertyFormat = 0;
- unsigned long itemsReturned, bytesRemaining;
- unsigned char *valueReturned = NULL;
- Window mainWindow;
-
- mainWindow = upw->clientWindow ? upw->clientWindow : upw->toplevelWindow;
- XGetWindowProperty(up->display, mainWindow,
- up->atoms._NET_WM_WINDOW_TYPE, 0,
- 1024, False, AnyPropertyType,
- &netWmPropertyType, &netWmPropertyFormat, &itemsReturned,
- &bytesRemaining, &valueReturned);
-
- if (UnityPlatformGetErrorCount(up)) {
- Debug("Error retrieving window type property\n");
- shouldBeRelevant = FALSE;
- goto out;
- }
-
- if (netWmPropertyType == XA_ATOM && itemsReturned && !bytesRemaining) {
- netWmWindowType = *((Atom *) valueReturned);
- }
- XFree(valueReturned);
-
- shouldBeRelevant = TRUE;
- if (netWmWindowType == up->atoms._NET_WM_WINDOW_TYPE_DESKTOP) {
- shouldBeRelevant = FALSE;
- upw->windowType = UNITY_WINDOW_TYPE_DESKTOP;
- up->desktopWindow = upw;
- } else if (netWmWindowType == up->atoms._NET_WM_WINDOW_TYPE_DND) {
- shouldBeRelevant = FALSE;
- } else if (netWmWindowType == up->atoms._NET_WM_WINDOW_TYPE_DOCK) {
- shouldBeRelevant = up->currentSettings[UNITY_UI_TASKBAR_VISIBLE];
- upw->windowType = UNITY_WINDOW_TYPE_DOCK;
- } else if (netWmWindowType == up->atoms._NET_WM_WINDOW_TYPE_UTILITY) {
- upw->windowType = UNITY_WINDOW_TYPE_PANEL;
- } else if (netWmWindowType == up->atoms._NET_WM_WINDOW_TYPE_DIALOG) {
- upw->windowType = UNITY_WINDOW_TYPE_DIALOG;
- } else if (netWmWindowType == up->atoms._NET_WM_WINDOW_TYPE_MENU
- || netWmWindowType == up->atoms._NET_WM_WINDOW_TYPE_POPUP_MENU
- || netWmWindowType == up->atoms._NET_WM_WINDOW_TYPE_DROPDOWN_MENU) {
- upw->windowType = UNITY_WINDOW_TYPE_MENU;
- } else if (netWmWindowType == up->atoms._NET_WM_WINDOW_TYPE_SPLASH) {
- upw->windowType = UNITY_WINDOW_TYPE_SPLASH;
- } else if (netWmWindowType == up->atoms._NET_WM_WINDOW_TYPE_TOOLBAR) {
- upw->windowType = UNITY_WINDOW_TYPE_TOOLBAR;
- } else if (netWmWindowType == up->atoms._NET_WM_WINDOW_TYPE_TOOLTIP) {
- upw->windowType = UNITY_WINDOW_TYPE_TOOLTIP;
- } else {
- upw->windowType = UNITY_WINDOW_TYPE_NORMAL;
- }
- }
- }
-
-out:
- ASSERT(shouldBeRelevant >= 0);
-
- Debug("Relevance for (%p) %#lx/%#lx/%#lx is %d (window type %d)\n",
- upw, upw->toplevelWindow, upw->clientWindow, upw->rootWindow,
- shouldBeRelevant, upw->windowType);
-
- UPWindowSetRelevance(up, upw, shouldBeRelevant ? TRUE : FALSE);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindow_SetUserTime --
- *
- * Updates the _NET_WM_USER_TIME property on a window so the window manager
- * will let us restack the window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Updated timestamp.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UPWindow_SetUserTime(UnityPlatform *up, // IN
- UnityPlatformWindow *upw) // IN
-{
- Atom dummy;
- Window focusWindow;
- Atom propertyType;
- int propertyFormat;
- unsigned long itemsReturned, bytesRemaining;
- unsigned char *valueReturned = NULL;
-
- focusWindow = upw->clientWindow ? upw->clientWindow : upw->toplevelWindow;
-
- XGetWindowProperty(up->display, focusWindow, up->atoms._NET_WM_USER_TIME_WINDOW, 0,
- 1024, False, XA_WINDOW, &propertyType, &propertyFormat,
- &itemsReturned, &bytesRemaining, &valueReturned);
- if (valueReturned) {
- focusWindow = *(Window *)valueReturned;
- XFree(valueReturned);
- }
-
- dummy = UnityPlatformGetServerTime(up);
- XChangeProperty(up->display, focusWindow,
- up->atoms._NET_WM_USER_TIME, XA_CARDINAL,
- 32, PropModeReplace, (unsigned char *)&dummy, 1);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowGetActualWindowAndPosition --
- *
- * Figures out the right arguments to call XMoveResizeWindow with when
- * moving/resizing a window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Puts the window and coordinates to use in 'actualWindow' and 'actualRect'.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowGetActualWindowAndPosition(UnityPlatform *up, // IN
- const UnityPlatformWindow *upw, // IN
- const UnityRect *orig, // IN
- const XWindowAttributes *origTop, // IN
- Window *actualWindow, // IN/OUT
- UnityRect *actualRect) // IN/OUT
-{
- XWindowAttributes clientWinAttr;
- Atom propertyType;
- int propertyFormat = 0;
- unsigned long itemsReturned = 0;
- unsigned long bytesRemaining;
- unsigned char *valueReturned = NULL;
- int frameSizeTop;
- int frameSizeBottom;
- int frameSizeLeft;
- int frameSizeRight;
-
- ASSERT(up);
- ASSERT(upw);
- ASSERT(orig);
- ASSERT(actualWindow);
- ASSERT(actualRect);
-
- *actualRect = *orig;
- if (!upw->clientWindow) {
- *actualWindow = upw->toplevelWindow;
- return;
- }
-
- *actualWindow = upw->clientWindow;
-
- /*
- * We need to figure out how to adjust the 'orig' rect (which is in toplevelWindow
- * coordinates) and turn it into clientWindow coordinates. Because window managers
- * ignore requests to modify their frame windows (toplevelWindow), we have to request
- * the change on the clientWindow instead.
- */
- if (UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_FRAME_EXTENTS)
- && XGetWindowProperty(up->display, upw->clientWindow, up->atoms._NET_FRAME_EXTENTS, 0,
- 1024, False, XA_CARDINAL,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, &valueReturned) == Success
- && propertyFormat == 32
- && itemsReturned >= 4) {
- Atom *atomValue = (Atom *)valueReturned;
-
- frameSizeLeft = atomValue[0];
- frameSizeRight = atomValue[1];
- frameSizeTop = atomValue[2];
- frameSizeBottom = atomValue[3];
- } else {
- /*
- * Query the current clientWindow and calculate how to adjust the frame coords to
- * client coords.
- */
- clientWinAttr.x = clientWinAttr.y = 0;
- clientWinAttr.width = origTop->width;
- clientWinAttr.height = origTop->height;
-
- XGetWindowAttributes(up->display, upw->clientWindow, &clientWinAttr);
-
- frameSizeLeft = clientWinAttr.x;
- frameSizeRight = origTop->width - (clientWinAttr.x + clientWinAttr.width);
- frameSizeTop = clientWinAttr.y;
- frameSizeBottom = origTop->height - (clientWinAttr.y + clientWinAttr.height);
- }
-
- /*
- * It turns out that with metacity, we don't have to adjust x/y for the frame size,
- * only the width & height. XXX we should see how other window managers behave.
- */
-#if 0
- actualRect->x += frameSizeLeft;
- actualRect->y += frameSizeTop;
-#endif
-
- actualRect->width -= frameSizeLeft + frameSizeRight;
- actualRect->height -= frameSizeTop + frameSizeBottom;
-
- XFree(valueReturned);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformMoveResizeWindow --
- *
- * Moves and/or resizes the given window to the specified location. Does not
- * attempt to move and/or resize window if (a) the destination rectangle does not
- * intersect with the virtual screen rectangle (b) window is minimized.
- *
- * If the input width & height match the current width & height, then this
- * function will end up just moving the window. Similarly if the input
- * x & y coordinates match the current coordinates, then it will end up just
- * resizing the window.
- *
- * Results:
- * Even if the move/resize operaion is not execuated or it fails, window's
- * current coordinates are always sent back.
- *
- * Function does not return FALSE if the attempt to move and/or resize fails.
- * This is because the host will be comparing input and output parameters to
- * decide whether the window really moved and/or resized.
- *
- * In a very rare case, when attempt to get window's current coordinates fail,
- * returns FALSE.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformMoveResizeWindow(UnityPlatform *up, // IN
- UnityWindowId window, // IN: Window handle
- UnityRect *moveResizeRect) // IN/OUT: Desired coordinates,
- // before and after
- // the operation.
-{
- UnityPlatformWindow *upw;
- Bool retval = FALSE;
- XWindowAttributes winAttr;
- XWindowAttributes newAttr;
- UnityRect desiredRect;
-
- ASSERT(moveResizeRect);
-
- upw = UPWindow_Lookup(up, window);
- if (!upw) {
- return FALSE;
- }
-
- desiredRect = *moveResizeRect;
-
- UnityPlatformResetErrorCount(up);
- XGetWindowAttributes(up->display, upw->toplevelWindow, &winAttr);
- if (UnityPlatformGetErrorCount(up)) {
- return FALSE;
- }
-
- if (winAttr.x == moveResizeRect->x
- && winAttr.y == moveResizeRect->y
- && winAttr.width == moveResizeRect->width
- && winAttr.height == moveResizeRect->height) {
- return TRUE;
- }
-
- /*
- * _NET_MOVERESIZE_WINDOW is preferable in general (because it saves us extra X
- * calls), but it is broken in metacity and there's no way to detect whether it works
- * or not.
- */
-#if defined(VM_CAN_TRUST__NET_MOVERESIZE_WINDOW)
- if (UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_MOVERESIZE_WINDOW)
- && upw->clientWindow) {
- Atom data[5] = {0, 0, 0, 0, 0};
-
- /*
- * The first datum in the EWMH _NET_MOVERESIZE_WINDOW message contains a bunch of
- * bits to signify what information is in the request and where the request came
- * from. The (0xF << 8) bits (lower nibble of the upper byte) signify that the request contains x, y, width, and
- * height data. The (2 << 12) bits (higher nibble of the upper byte) signifies that the request was made by the
- * pager/taskbar. StaticGravity is 10 in the lower byte.
- */
- data[0] = (0xF << 8) | (2 << 12) | StaticGravity;
-
- data[1] = moveResizeRect->x;
- data[2] = moveResizeRect->y;
- data[3] = moveResizeRect->width;
- data[4] = moveResizeRect->height;
- UnityPlatformSendClientMessage(up, upw->rootWindow, upw->clientWindow,
- up->atoms._NET_MOVERESIZE_WINDOW,
- 32, 5, data);
- Debug("MoveResizeWindow implemented using _NET_MOVERESIZE_WINDOW\n");
- } else
-#endif
- {
- if (upw->desktopNumber == (int)up->desktopInfo.currentDesktop ||
- upw->desktopNumber == -1) {
- UnityRect actualRect;
- Window actualWindow;
-
- UPWindowGetActualWindowAndPosition(up, upw, moveResizeRect, &winAttr, &actualWindow, &actualRect);
-
- XMoveResizeWindow(up->display, actualWindow,
- actualRect.x, actualRect.y,
- actualRect.width, actualRect.height);
- Debug("MoveResizeWindow implemented using XMoveResizeWindow (requested (%d, %d) +(%d, %d) on %#lx\n",
- actualRect.x, actualRect.y, actualRect.width, actualRect.height,
- actualWindow);
- } else {
- Debug("Trying to move window %#lx that is on desktop %d instead of the current desktop %u\n",
- upw->toplevelWindow, upw->desktopNumber, up->desktopInfo.currentDesktop);
- return FALSE;
- }
- }
-
- XSync(up->display, False);
- XGetWindowAttributes(up->display, upw->toplevelWindow, &newAttr);
- moveResizeRect->x = newAttr.x;
- moveResizeRect->y = newAttr.y;
- moveResizeRect->width = newAttr.width;
- moveResizeRect->height = newAttr.height;
-
- retval = TRUE;
-
- Debug("MoveResizeWindow(%#lx/%#lx): original (%d,%d)+(%d,%d), desired (%d,%d)+(%d,%d), actual (%d,%d)+(%d,%d) = %d\n",
- upw->toplevelWindow, upw->clientWindow,
- winAttr.x, winAttr.y, winAttr.width, winAttr.height,
- desiredRect.x, desiredRect.y, desiredRect.width, desiredRect.height,
- moveResizeRect->x, moveResizeRect->y,
- moveResizeRect->width, moveResizeRect->height,
- retval);
-
- return retval;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformCloseWindow --
- *
- * Close the window. Send WM_DELETE message to the specified window.
- * Just because the message was posted successfully, doesn't mean the
- * window will be closed (this is up to the underlying application/user
- * actions).
- *
- * Results:
- * TRUE if we were successful in posting the close message to the window.
- * FALSE otherwise.
- *
- * Side effects:
- * The window might be closed (and, potentially, an application exits)
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformCloseWindow(UnityPlatform *up, // IN: Platform data
- UnityWindowId window) // IN: window handle
-{
- UnityPlatformWindow *upw;
-
- ASSERT(up);
-
- upw = UPWindow_Lookup(up, window);
-
- Debug("Closing window %#x\n", window);
-
- if (!upw) {
- return FALSE;
- }
-
- if (upw->clientWindow &&
- UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_CLOSE_WINDOW)) {
- Atom data[] = {0,
- 2, // Bit to indicate that the pager requested it
- 0,
- 0,
- 0};
- data[0] = UnityPlatformGetServerTime(up);
- UnityPlatformSendClientMessage(up, upw->rootWindow, upw->clientWindow,
- up->atoms._NET_CLOSE_WINDOW, 32, 5,
- data);
- } else if (UPWindow_ProtocolSupported(up, upw, UNITY_X11_WIN_WM_DELETE_WINDOW)){
- Atom data[1];
- Window destWin = upw->clientWindow ? upw->clientWindow : upw->toplevelWindow;
-
- data[0] = up->atoms.WM_DELETE_WINDOW;
-
- UnityPlatformSendClientMessage(up, destWin, destWin,
- up->atoms.WM_DELETE_WINDOW, 32, 1,
- data);
- } else {
- XDestroyWindow(up->display, upw->toplevelWindow);
- XFlush(up->display);
- }
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformGetWindowPath --
- *
- * Get the information needed to re-launch a window and retrieve further
- * information on it.
- *
- * windowPathUtf8 uniquely identifies an X11 window (windowUri),
- * execPathUtf8 uniquely identifies the window's owning
- * executable (execUri).
- *
- * windowUri is handy for getting icons and other data associated with a
- * specific window, whereas execUri is handy for uniquely identifying
- * applications for GHI. (The host uses our returned strings to uniquely
- * identify applications, and we don't want it to consider the window ID
- * for that purpose, as it causes the host to believe that two windows
- * from the same application are really associated with separate
- * applications.)
- *
- * Results:
- * TRUE if everything went ok, FALSE otherwise.
- *
- * Side effects:
- * Original buffer contents are overwritten.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformGetWindowPath(UnityPlatform *up, // IN: Platform data
- UnityWindowId window, // IN: window handle
- DynBuf *windowPathUtf8, // IN/OUT: full path to the window
- DynBuf *execPathUtf8) // IN/OUT: full path to the binary
-{
- UnityPlatformWindow *upw;
- bool retval = false;
-
- ASSERT(up);
-
- upw = UPWindow_Lookup(up, window);
-
- if (!upw) {
- Debug("GetWindowPath FAILED!\n");
- return FALSE;
- }
-
- WindowPathFactory::WindowPathPair pathPair;
- retval = up->wpFactory->FindByXid(upw->clientWindow ? upw->clientWindow :
- upw->toplevelWindow, pathPair);
-
- if (!retval) {
- Debug("GetWindowPath didn't know how to identify the window...\n");
- } else {
- /*
- * FindByXid gives us 2 paths:
- * 1. Absolute path of executable owning the window.
- * 2. Desktop entry file for said application, if possible.
- *
- * The desktop entry references additional resources, such as icons,
- * localized names, external launchers, etc., so it's the preferred
- * way to refer to an application.
- *
- * Now, we're returning nearly the same path to our caller with one
- * subtle difference: one path includes a WindowXID URL parameter.
- * Given the desktop entry or executable path returned by FindByXid,
- * we'll just massage as needed into the caller's output DynBufs.
- */
- Debug("GetWindowPath window %#x results in: \n"
- " desktopEntry = %s\n"
- " execPath = %s\n",
- window, pathPair.second.c_str(), pathPair.first.c_str());
-
- DynBuf_SetSize(windowPathUtf8, 0);
- DynBuf_SetSize(execPathUtf8, 0);
-
- std::ostringstream ostr;
- ostr << "file://";
- ostr << (pathPair.second.empty() ? pathPair.first : pathPair.second);
- DynBuf_AppendString(execPathUtf8, ostr.str().c_str());
-
- ostr << "?WindowXID=" << window;
- DynBuf_AppendString(windowPathUtf8, ostr.str().c_str());
-
- retval = true;
- }
-
- return retval;
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityPlatformGetWindowContents --
- *
- * Read the correct bits off the window regardless of whether it's minimized
- * or obscured. Return the result as a PNG in the imageData DynBuf.
- *
- * Results:
- * Returns TRUE in case success and FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformGetWindowContents(UnityPlatform *up, // IN
- UnityWindowId window, // IN
- DynBuf *imageData, // IN
- uint32 *width, // OUT
- uint32 *height) // OUT
-{
- UnityPlatformWindow *upw;
- Pixmap pixmap = 0;
- XWindowAttributes attrs;
- XImage *ximage = NULL;
- GC xgc = 0;
- XGCValues gcvalues;
- Bool result = FALSE;
- ImageInfo vmimage = { 0 };
-
- ASSERT(up);
- ASSERT(imageData);
- ASSERT(width);
- ASSERT(height);
-
- upw = UPWindow_Lookup(up, window);
-
- if (!upw) {
- return FALSE;
- }
-
- UnityPlatformResetErrorCount(up);
- if (!XGetWindowAttributes(up->display, upw->toplevelWindow, &attrs)
- || UnityPlatformGetErrorCount(up)) {
- return FALSE;
- }
- pixmap = XCreatePixmap(up->display, upw->toplevelWindow,
- attrs.width, attrs.height, attrs.depth);
- if (UnityPlatformGetErrorCount(up)) {
- return FALSE;
- }
-
- gcvalues.background = gcvalues.foreground = 0;
- gcvalues.subwindow_mode = IncludeInferiors;
- gcvalues.fill_style = FillSolid;
- XFillRectangle(up->display, pixmap, xgc, 0, 0, attrs.width, attrs.height);
- xgc = XCreateGC(up->display, pixmap,
- GCFillStyle |
- GCBackground |
- GCForeground |
- GCSubwindowMode,
- &gcvalues);
- if (UnityPlatformGetErrorCount(up)) {
- goto out;
- }
-
- XCopyArea(up->display, upw->toplevelWindow, pixmap, xgc, 0, 0,
- attrs.width, attrs.height, 0, 0);
- if (UnityPlatformGetErrorCount(up)) {
- goto out;
- }
-
- ximage = XGetImage(up->display, pixmap, 0, 0,
- attrs.width, attrs.height, ~0, XYPixmap);
-
- if (!ximage || UnityPlatformGetErrorCount(up)) {
- goto out;
- }
-
- vmimage.width = ximage->width;
- vmimage.height = ximage->height;
- vmimage.depth = ximage->depth;
- vmimage.bpp = ximage->bitmap_unit;
- vmimage.redMask = ximage->red_mask;
- vmimage.greenMask = ximage->green_mask;
- vmimage.blueMask = ximage->blue_mask;
- vmimage.bytesPerLine = ximage->bytes_per_line;
- vmimage.data = (unsigned char*)ximage->data;
-
- if (ImageUtil_ConstructPNGBuffer(&vmimage, NULL, imageData)) {
- result = TRUE;
- }
-
- if (result) {
- *width = vmimage.width;
- *height = vmimage.height;
- }
-
- out:
- if (ximage) {
- XDestroyImage(ximage);
- }
-
- if (xgc) {
- XFreeGC(up->display, xgc);
- }
-
- if (pixmap) {
- XFreePixmap(up->display, pixmap);
- }
-
- return result;
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityPlatformGetIconData --
- *
- * Read part or all of a particular icon on a window. Return the result as a PNG in
- * the imageData DynBuf, and also return the full length of the PNG in fullLength.
- *
- * Results:
- * Returns TRUE if successful, and FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformGetIconData(UnityPlatform *up, // IN
- UnityWindowId window, // IN
- UnityIconType iconType, // IN
- UnityIconSize iconSize, // IN
- uint32 dataOffset, // IN
- uint32 dataLength, // IN
- DynBuf *imageData, // OUT
- uint32 *fullLength) // OUT
-{
- UnityPlatformWindow *upw;
-
- ASSERT(up);
- ASSERT(fullLength);
- ASSERT(imageData);
-
- upw = UPWindow_Lookup(up, window);
-
- if (!upw || !upw->clientWindow || iconType != UNITY_ICON_TYPE_MAIN) {
- return FALSE;
- }
-
- Debug("GetIconData %#lx\n", (Window)window);
-
- if (!DynBuf_GetSize(&upw->iconPng.data)
- || (upw->iconPng.size != iconSize)
- || (upw->iconPng.type != iconType)) {
- GPtrArray *pixbufs;
- Bool gotIcons = FALSE;
-
- pixbufs = AppUtil_CollectIconArray(NULL, upw->clientWindow);
-
- if (pixbufs && pixbufs->len) {
- GdkPixbuf *pixbuf;
- gchar *pngData;
- gsize pngDataSize;
-
- pixbuf = (GdkPixbuf*)g_ptr_array_index(pixbufs, 0);
-
- if (gdk_pixbuf_save_to_buffer(pixbuf, &pngData, &pngDataSize,
- "png", NULL, NULL)) {
- DynBuf_Attach(&upw->iconPng.data, pngDataSize, pngData);
- gotIcons = TRUE;
- } else {
- DynBuf_SetSize(&upw->iconPng.data, 0);
- }
-
- upw->iconPng.size = iconSize;
- upw->iconPng.type = iconType;
- }
-
- AppUtil_FreeIconArray(pixbufs);
-
- if (!gotIcons) {
- return FALSE;
- }
- }
-
- *fullLength = DynBuf_GetSize(&upw->iconPng.data);
- if (dataOffset >= *fullLength) {
- DynBuf_SetSize(imageData, 0);
- } else {
- uint32 realLength;
-
- if ((dataOffset + dataLength) > *fullLength) {
- realLength = *fullLength - dataOffset;
- } else {
- realLength = dataLength;
- }
- DynBuf_Enlarge(imageData, realLength);
- DynBuf_SetSize(imageData, realLength);
-
- memcpy(imageData->data,
- ((const char *)DynBuf_Get(&upw->iconPng.data)) + dataOffset,
- realLength);
- }
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformUnminimizeWindow --
- *
- * Tell the window to restore from the minimized state to its original
- * size.
- *
- * Results:
- * TRUE always
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformUnminimizeWindow(UnityPlatform *up, // IN
- UnityWindowId window) // IN
-{
- UnityPlatformWindow *upw;
-
- ASSERT(up);
-
- upw = UPWindow_Lookup(up, window);
-
- if (!upw || !upw->clientWindow) {
- Debug("Restoring FAILED!\n");
- return FALSE;
- }
-
- Debug("%s(%#lx)\n", __func__, upw->toplevelWindow);
- if (upw->isMinimized) {
- Atom data[5] = {0, 0, 0, 0, 0};
-
- Debug("Restoring window %#x\n", window);
-
- upw->isMinimized = FALSE;
- upw->wantInputFocus = TRUE;
-
- /*
- * Okay, client messages to update _NET_WM_STATE are intended only for
- * /mapped/ windows. (That's my interpretation considering that wm-spec
- * only mentions mapped windows, and window managers seem to ignore the
- * request for minimized windows.)
- *
- * Rather than directly mapping the window, we'll instead request that
- * the window manager activate it. Mapping the window has a negative
- * consequence of stripping the window of its _NET_WM_STATE and
- * _NET_WM_DESKTOP properties. This is most visible when unminimizing
- * a sticky window -- the result is that it would lose its stickiness.
- */
-
- data[0] = 2;
- data[1] = UnityPlatformGetServerTime(up);
- data[2] = 0;
- UnityPlatformSendClientMessage(up, upw->rootWindow, upw->clientWindow,
- up->atoms._NET_ACTIVE_WINDOW, 32, 4, data);
-
- data[0] = _NET_WM_STATE_REMOVE;
- data[1] = up->atoms._NET_WM_STATE_HIDDEN;
- data[2] = up->atoms._NET_WM_STATE_MINIMIZED;
- data[3] = 2; // Message is from the pager/taskbar
- UnityPlatformSendClientMessage(up, upw->rootWindow, upw->clientWindow,
- up->atoms._NET_WM_STATE, 32, 4, data);
- } else {
- Debug("Window %#x is already restored\n", window);
- }
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowProcessPropertyEvent --
- *
- * Processes an notification that a property has changed on an X11 window.
- *
- * N.B. The UPWindowPushFullUpdate method creates a fake 'xevent' based on all the
- * properties are set initially on a window, so before passing 'xevent' down the
- * call chain, or using any additional fields from it, make sure that
- * UPWindowPushFullUpdate fills in those fields properly.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowProcessPropertyEvent(UnityPlatform *up, // IN
- UnityPlatformWindow *upw, // IN
- const XEvent *xevent) // IN
-{
- Atom eventAtom;
-
- ASSERT(up);
- ASSERT(upw);
- ASSERT(xevent);
-
- eventAtom = xevent->xproperty.atom;
- if (eventAtom == up->atoms._NET_WM_STATE ||
- eventAtom == up->atoms.WM_STATE) {
- UPWindowUpdateState(up, upw, &xevent->xproperty);
- if (eventAtom == up->atoms.WM_STATE) {
- UPWindowUpdateIcon(up, upw);
- }
- } else if (eventAtom == up->atoms.WM_NAME) {
- UPWindowUpdateTitle(up, upw);
- } else if (eventAtom == up->atoms.WM_PROTOCOLS) {
- UPWindowUpdateProtocols(up, upw);
- } else if (eventAtom == up->atoms._NET_WM_ALLOWED_ACTIONS) {
- UPWindowUpdateActions(up, upw);
- } else if (eventAtom == up->atoms._NET_WM_WINDOW_TYPE) {
- UPWindowUpdateType(up, upw);
- } else if (eventAtom == up->atoms._NET_WM_ICON
- || eventAtom == up->atoms.WM_ICON) {
- UPWindowUpdateIcon(up, upw);
- } else if (eventAtom == up->atoms._NET_WM_DESKTOP) {
- UPWindowUpdateDesktop(up, upw);
- } else if (eventAtom == up->atoms._NET_FRAME_EXTENTS) {
- UPWindowUpdateFrameExtents(up, upw);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowProcessConfigureEvent --
- *
- * Processes an notification that the window configuration has changed.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowProcessConfigureEvent(UnityPlatform *up, // IN
- UnityPlatformWindow *upw, // IN
- const XEvent *xevent) // IN
-{
- if (xevent->xconfigure.window == upw->toplevelWindow) {
- const int border_width = xevent->xconfigure.border_width;
- int x = xevent->xconfigure.x;
- int y = xevent->xconfigure.y;
- int xprime;
- int yprime;
-
- xprime = x + xevent->xconfigure.width + border_width;
- yprime = y + xevent->xconfigure.height + border_width;
- x -= border_width;
- y -= border_width;
-
-#ifdef VMX86_DEVEL
- Debug("Moving window %#lx/%#lx to (%d, %d) +(%d, %d)\n",
- upw->toplevelWindow, upw->clientWindow,
- x, y, xprime - x, yprime - y);
-#endif
-
- /*
- * If these are the same, then the window hasn't been reparented by
- * the window manager, and its window decorations are accounted for
- * by the values of the _NET_FRAME_EXTENTS property.
- */
- if (upw->toplevelWindow == upw->clientWindow) {
- x -= upw->frameExtents[0]; // left
- y -= upw->frameExtents[2]; // top
- xprime += upw->frameExtents[1]; // right
- yprime += upw->frameExtents[3]; // bottom
- }
-
- UnityWindowTracker_MoveWindow(up->tracker, upw->toplevelWindow,
- x, y, xprime, yprime);
-
- if ((xevent->xconfigure.above != None && !upw->lowerWindow)
- || (xevent->xconfigure.above == None && upw->lowerWindow)
- || (upw->lowerWindow && xevent->xconfigure.above
- != upw->lowerWindow->toplevelWindow)) {
- Debug("Marking window %#lx/%#lx for restacking\n",
- upw->toplevelWindow, upw->clientWindow);
- UPWindow_Restack(up, upw, xevent->xconfigure.above);
- }
- } else {
- Debug("ProcessConfigureEvent skipped event on window %#lx (upw was %#lx/%#lx)\n",
- xevent->xconfigure.window, upw->toplevelWindow, upw->clientWindow);
- }
-
-#ifdef VMX86_DEVEL
- CompareStackingOrder(up, upw->rootWindow, __func__);
-#endif
-}
-
-
-#if defined(VM_HAVE_X11_SHAPE_EXT)
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowUpdateShape --
- *
- * Updates the window shape.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Notification to the window tracker
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowUpdateShape(UnityPlatform *up, // IN
- UnityPlatformWindow *upw) // IN
-{
- RegionPtr clipRegion = NULL;
- RegionPtr boundingRegion = NULL;
- RegionPtr region = NULL;
- XRectangle *rects = NULL;
- int rectCount;
- int rectOrdering;
-
- /*
- * Retrieve the X11 'clipping shape' (the window shape including its border) and turn
- * it into a region.
- */
- UnityPlatformResetErrorCount(up);
- rects = XShapeGetRectangles(up->display, upw->toplevelWindow, ShapeClip,
- &rectCount, &rectOrdering);
- if (!UnityPlatformGetErrorCount(up) && rects && rectCount) {
- xRectangle *vmRects;
- int i;
-
- vmRects = (xRectangle*)alloca(rectCount * (sizeof *vmRects));
- memset(vmRects, 0, rectCount * (sizeof *vmRects));
- for (i = 0; i < rectCount; i++) {
- ASSERT(rects[i].width);
- ASSERT(rects[i].height);
- vmRects[i].x = rects[i].x;
- vmRects[i].y = rects[i].y;
- vmRects[i].width = rects[i].width;
- vmRects[i].height = rects[i].height;
- vmRects[i].info.type = UpdateRect;
- }
-
- clipRegion = miRectsToRegion(rectCount, vmRects, 0);
- }
- XFree(rects); rects = NULL;
- rectCount = 0;
-
- /*
- * The X Shape Extension operates on unshaped windows by using default bounding
- * and clipping regions. I.e., XShapeGetRectangles will return a single rectangle
- * for an unshaped window. Without the following test, we'd end up informing the
- * Unity client that this window can be described by a single rectangle region,
- * and it'd expect further region updates when the window's geometry changes.
- *
- * This wouldn't be a problem, except we don't receive XShapeEvents on these
- * windows when they're resized. To work around this, we make sure that the UWT
- * knows that unshaped windows are exactly that.
- */
- {
- int bShaped;
- int cShaped;
- int dummy;
- uint udummy;
-
- XShapeQueryExtents(up->display, upw->toplevelWindow,
- &bShaped, &dummy, &dummy, &udummy, &udummy,
- &cShaped, &dummy, &dummy, &udummy, &udummy);
- if (!bShaped && !cShaped) {
- UnityWindowTracker_ChangeWindowRegion(up->tracker, upw->toplevelWindow, 0);
- return;
- }
- }
-
- UnityPlatformResetErrorCount(up);
-
- /*
- * Retrieve the X11 'clipping shape' (the window shape of the window without its
- * border) and turn it into a region.
- */
- rects = XShapeGetRectangles(up->display, upw->toplevelWindow, ShapeBounding,
- &rectCount, &rectOrdering);
- if (!UnityPlatformGetErrorCount(up)
- && rects && rectCount) {
- xRectangle *vmRects;
- int i;
-
- vmRects = (xRectangle*)alloca(rectCount * (sizeof *vmRects));
- memset(vmRects, 0, rectCount * (sizeof *vmRects));
- for (i = 0; i < rectCount; i++) {
- ASSERT(rects[i].width);
- ASSERT(rects[i].height);
- vmRects[i].x = rects[i].x;
- vmRects[i].y = rects[i].y;
- vmRects[i].width = rects[i].width;
- vmRects[i].height = rects[i].height;
- vmRects[i].info.type = UpdateRect;
- }
-
- boundingRegion = miRectsToRegion(rectCount, vmRects, 0);
- }
- XFree(rects);
-
- if (boundingRegion && clipRegion) {
- region = miRegionCreate(NULL, 2);
- miIntersect(region, clipRegion, boundingRegion);
- } else if (clipRegion) {
- region = clipRegion; clipRegion = NULL;
- } else if (boundingRegion) {
- region = boundingRegion; boundingRegion = NULL;
- }
-
- UnityWindowTracker_ChangeWindowRegion(up->tracker, upw->toplevelWindow, region);
- if (clipRegion) {
- miRegionDestroy(clipRegion);
- }
- if (boundingRegion) {
- miRegionDestroy(boundingRegion);
- }
- if (region) {
- miRegionDestroy(region);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowProcessShapeEvent --
- *
- * Processes an notification that the non-rectangular window shape has changed.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowProcessShapeEvent(UnityPlatform *up, // IN
- UnityPlatformWindow *upw, // IN
- const XEvent *xevent) // IN
-{
- XShapeEvent *sev;
-
- ASSERT(up);
- ASSERT(upw);
- ASSERT(xevent->type == (up->shapeEventBase + ShapeNotify));
-
- sev = (XShapeEvent *)xevent;
- ASSERT (sev->window == upw->toplevelWindow ||
- sev->window == upw->clientWindow);
-
- if (sev->shaped) {
- UPWindowUpdateShape(up, upw);
- } else {
- UnityWindowTracker_ChangeWindowRegion(up->tracker, upw->toplevelWindow, NULL);
- }
-}
-#endif
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformWindowProcessEvent --
- *
- * Handle an event on a typical window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Many.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UPWindow_ProcessEvent(UnityPlatform *up, // IN
- UnityPlatformWindow *upw, // IN
- Window realEventWindow, // IN
- const XEvent *xevent) // IN
-{
- Bool eventHandled = TRUE;
-
- ASSERT(up);
- ASSERT(upw);
- ASSERT(xevent);
-
- UPWindow_CheckRelevance(up, upw, xevent);
-
- switch (xevent->type) {
- case KeyPress:
- case KeyRelease:
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- case EnterNotify:
- case LeaveNotify:
- case KeymapNotify:
- case Expose:
- case GraphicsExpose:
- case NoExpose:
- case MapRequest:
- case ResizeRequest:
- case CirculateRequest:
- case SelectionClear:
- case SelectionRequest:
- case SelectionNotify:
- case ColormapNotify:
- case ClientMessage:
- case GravityNotify:
- case VisibilityNotify:
- case MappingNotify:
- case ReparentNotify:
- case ConfigureRequest:
- break; // No extra processing on these for now
-
- case CreateNotify:
- /* Do nothing. The UPWindow has already been created. */
- break;
-
- case FocusIn:
- if (upw->isRelevant) {
- UnityWindowInfo *info;
- info = UnityWindowTracker_LookupWindow(up->tracker, upw->toplevelWindow);
-
- UnityWindowTracker_ChangeWindowState(up->tracker,
- upw->toplevelWindow,
- info->state | UNITY_WINDOW_STATE_IN_FOCUS);
- }
- break;
-
- case FocusOut:
- if (upw->isRelevant) {
- UnityWindowInfo *info;
- info = UnityWindowTracker_LookupWindow(up->tracker, upw->toplevelWindow);
-
- UnityWindowTracker_ChangeWindowState(up->tracker,
- upw->toplevelWindow,
- (info->state
- & ~UNITY_WINDOW_STATE_IN_FOCUS));
- }
- break;
-
- case DestroyNotify:
- Debug("Destroying window (%p) %#lx/%#lx\n",
- upw, upw->toplevelWindow, upw->clientWindow);
-
- /*
- * Release the UnityPlatform object's reference to this UnityPlatformWindow,
- */
- upw->windowType = UNITY_WINDOW_TYPE_NONE;
- upw->deleteWhenSafe = TRUE;
-#ifdef VMX86_DEVEL
- CompareStackingOrder(up, upw->rootWindow, __func__);
-#endif
- break;
-
- case UnmapNotify:
- upw->wantInputFocus = FALSE;
- upw->isViewable = FALSE;
- break;
-
- case MapNotify:
- /*
- * This is here because we want to set input focus as part of UnminimizeWindow, but
- * can't call XSetInputFocus until the window has actually been shown.
- */
- if (upw->wantInputFocus && upw->clientWindow) {
- XSetInputFocus(up->display, upw->clientWindow, RevertToParent,
- UnityPlatformGetServerTime(up));
- upw->wantInputFocus = FALSE;
- }
-
- upw->isViewable = TRUE;
- break;
-
- case CirculateNotify:
- if (upw->isRelevant) {
- UPWindow_Restack(up, upw,
- (up->topWindow && xevent->xcirculate.place == PlaceOnTop)
- ? up->topWindow->toplevelWindow : None);
- }
- break;
-
- case PropertyNotify:
- UPWindowProcessPropertyEvent(up, upw, xevent);
- break;
-
- case ConfigureNotify:
- UPWindowProcessConfigureEvent(up, upw, xevent);
- break;
-
- default:
- eventHandled = FALSE; // Unknown "regular" event
- break;
- }
-
- if (!eventHandled) { // Handle extension events here
-#if defined(VM_HAVE_X11_SHAPE_EXT)
- if (up->shapeEventBase &&
- xevent->type == (up->shapeEventBase + ShapeNotify)) {
- UPWindowProcessShapeEvent(up, upw, xevent);
- eventHandled = TRUE;
- }
-#endif
-
- ASSERT(eventHandled);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowUpdateTitle --
- *
- * Tells the window tracker about the window's latest title
- *
- * Results:
- * None.
- *
- * Side effects:
- * Notification to the window tracker
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowUpdateTitle(UnityPlatform *up, // IN
- UnityPlatformWindow *upw) // IN
-{
- Atom propertyType;
- int propertyFormat;
- unsigned long itemsReturned;
- unsigned long bytesRemaining;
- unsigned char *valueReturned = NULL;
- DynBuf titleBuf;
-
- if (!upw->clientWindow) {
- return;
- }
-
- if (XGetWindowProperty(up->display, upw->clientWindow, up->atoms.WM_NAME, 0,
- 1024, False, AnyPropertyType,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, &valueReturned)
- != Success) {
- /*
- * Some random error occurred - perhaps the window disappeared
- */
- return;
- }
-
- if (bytesRemaining != 0) {
- Log("Skipping title update for window %#lx. Title too long.\n",
- upw->clientWindow);
- return;
- }
-
- /*
- * propertyFormat tells us (in bits) the size of each item returned. Let's
- * convert that to bytes. See XGetWindowProperty(3) for details.
- */
- size_t bytesRead = itemsReturned * propertyFormat / 8;
- Glib::ustring newTitle;
-
- if (bytesRead) { // i.e. valueReturned isn't empty
- if ( propertyType == XA_STRING
- || propertyType == up->atoms.UTF8_STRING) {
- /*
- * Insert() used because NUL termination isn't guaranteed. (Is that
- * really the case? TODO: Look this up.)
- */
- newTitle.insert(0, (const char *)valueReturned, bytesRead);
- } else if (propertyType == up->atoms.COMPOUND_TEXT) {
- /*
- * COMPOUND_TEXT strings may contain characters outside the ASCII set.
- * We'll convert these to something usable (*cough*UTF-8*cough*) via
- * our trusty good pal, Gdk.
- */
- gchar **utf8List = NULL;
- gint nconverted;
- nconverted = gdk_text_property_to_utf8_list(
- gdk_x11_xatom_to_atom(up->atoms.COMPOUND_TEXT), propertyFormat,
- valueReturned, bytesRead, &utf8List);
- if (nconverted) {
- newTitle.assign(utf8List[0]);
- }
- g_strfreev(utf8List);
- }
- }
- XFree(valueReturned);
-
- DynBuf_Init(&titleBuf);
- DynBuf_Append(&titleBuf, newTitle.c_str(), newTitle.bytes() + 1);
- Debug("Set title of window %#lx to %s\n",
- upw->clientWindow, (char *)DynBuf_Get(&titleBuf));
- UnityWindowTracker_SetWindowTitle(up->tracker, (UnityWindowId) upw->toplevelWindow,
- &titleBuf);
- DynBuf_Destroy(&titleBuf);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowUpdateType --
- *
- * Tells the window tracker about the window's latest type
- *
- * Results:
- * None.
- *
- * Side effects:
- * Notification to the window tracker
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowUpdateType(UnityPlatform *up, // IN
- UnityPlatformWindow *upw) // IN
-{
- ASSERT(up);
- ASSERT(upw);
-
- /*
- * upw->windowType was previously updated by the CheckRelevance method.
- */
- UnityWindowTracker_ChangeWindowType(up->tracker,
- upw->toplevelWindow,
- upw->windowType);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowUpdateProtocols --
- *
- * Updates the list of protocols supported by the window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Notification to the window tracker
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowUpdateProtocols(UnityPlatform *up, // IN
- UnityPlatformWindow *upw) // IN
-{
- Atom propertyType;
- int propertyFormat;
- unsigned long itemsReturned;
- unsigned long bytesRemaining;
- Atom *valueReturned = NULL;
- uint i;
-
- if (!upw->clientWindow) {
- return;
- }
-
- if (XGetWindowProperty(up->display, upw->clientWindow, up->atoms.WM_STATE, 0,
- 1024, False, AnyPropertyType,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, (unsigned char **) &valueReturned)
- != Success) {
- /*
- * Some random error occurred - perhaps the window disappeared.
- */
- return;
- }
-
- if (propertyType != up->atoms.WM_STATE
- || propertyFormat != 32) {
- itemsReturned = 0;
- }
-
- memset(upw->windowProtocols, 0, sizeof upw->windowProtocols);
- for (i = 0; i < itemsReturned; i++) {
- UnityX11WinProtocol proto;
-
- if (valueReturned[i] == up->atoms.WM_DELETE_WINDOW) {
- proto = UNITY_X11_WIN_WM_DELETE_WINDOW;
- } else {
- continue;
- }
-
- upw->windowProtocols[proto] = TRUE;
- }
- XFree(valueReturned);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowUpdateActions --
- *
- * Updates the window attributes based on a new _NET_WM_ALLOWED_ACTIONS attribute.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Notification to the window tracker
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowUpdateActions(UnityPlatform *up, // IN
- UnityPlatformWindow *upw) // IN
-{
- Atom propertyType;
- int propertyFormat;
- unsigned long itemsReturned = 0;
- unsigned long bytesRemaining;
- Atom *valueReturned = NULL;
- uint i;
- Bool curAttrValues[UNITY_MAX_ATTRIBUTES];
- Bool attrsAreSet[UNITY_MAX_ATTRIBUTES];
- Bool haveHorizMax;
- Bool haveVertMax;
-
- if (!upw->clientWindow) {
- return;
- }
-
- memset(curAttrValues, 0, sizeof curAttrValues);
- memset(attrsAreSet, 0, sizeof attrsAreSet);
- haveHorizMax = haveVertMax = FALSE;
-
- /*
- * List of attributes that we know how to process from the ALLOWED_ACTIONS list. If we
- * don't find these in the ALLOWED_ACTIONS list, and they are supported by the window
- * manager, then we report that they're FALSE (set by the first memset above).
- */
- attrsAreSet[UNITY_WINDOW_ATTR_MINIMIZABLE] =
- UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_WM_ACTION_MINIMIZE);
- attrsAreSet[UNITY_WINDOW_ATTR_MAXIMIZABLE] =
- UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_WM_ACTION_MAXIMIZE_HORZ) &&
- UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_WM_ACTION_MAXIMIZE_VERT);
- attrsAreSet[UNITY_WINDOW_ATTR_CLOSABLE] =
- UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_WM_ACTION_CLOSE);
- attrsAreSet[UNITY_WINDOW_ATTR_FULLSCREENABLE] =
- UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_WM_ACTION_FULLSCREEN);
- attrsAreSet[UNITY_WINDOW_ATTR_SHADEABLE] =
- UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_WM_ACTION_SHADE);
- attrsAreSet[UNITY_WINDOW_ATTR_STICKABLE] =
- UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_WM_ACTION_STICK);
-
- if (XGetWindowProperty(up->display, upw->clientWindow,
- up->atoms._NET_WM_ALLOWED_ACTIONS, 0,
- 1024, False, XA_ATOM,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, (unsigned char **) &valueReturned)
- == Success
- && propertyFormat == 32) {
- for (i = 0; i < itemsReturned; i++) {
- UnityWindowAttribute attr;
- Bool attrValue = TRUE;
-
- if (valueReturned[i] == up->atoms._NET_WM_ACTION_MINIMIZE) {
- attr = UNITY_WINDOW_ATTR_MINIMIZABLE;
- } else if (valueReturned[i] == up->atoms._NET_WM_ACTION_MAXIMIZE_HORZ) {
- haveHorizMax = TRUE;
- continue;
- } else if (valueReturned[i] == up->atoms._NET_WM_ACTION_MAXIMIZE_VERT) {
- haveVertMax = TRUE;
- continue;
- } else if (valueReturned[i] == up->atoms._NET_WM_ACTION_CLOSE) {
- attr = UNITY_WINDOW_ATTR_CLOSABLE;
- } else if (valueReturned[i] == up->atoms._NET_WM_ACTION_FULLSCREEN) {
- attr = UNITY_WINDOW_ATTR_FULLSCREENABLE;
- } else if (valueReturned[i] == up->atoms._NET_WM_ACTION_SHADE) {
- attr = UNITY_WINDOW_ATTR_SHADEABLE;
- } else if (valueReturned[i] == up->atoms._NET_WM_ACTION_STICK) {
- attr = UNITY_WINDOW_ATTR_STICKABLE;
- } else {
- continue;
- }
-
- curAttrValues[attr] = attrValue;
- attrsAreSet[attr] = TRUE;
- }
- XFree(valueReturned);
- } else {
- curAttrValues[UNITY_WINDOW_ATTR_MINIMIZABLE] = TRUE;
- attrsAreSet[UNITY_WINDOW_ATTR_MINIMIZABLE] = TRUE;
- }
-
- curAttrValues[UNITY_WINDOW_ATTR_MAXIMIZABLE] = (haveHorizMax && haveVertMax);
- attrsAreSet[UNITY_WINDOW_ATTR_MAXIMIZABLE] = TRUE;
-
- for (i = 0; i < UNITY_MAX_ATTRIBUTES; i++) {
- if (attrsAreSet[i]) {
- UnityWindowTracker_ChangeWindowAttribute(up->tracker, upw->toplevelWindow,
- (UnityWindowAttribute)i, curAttrValues[i]);
- }
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowGetDesktop --
- *
- * Retrieve's the current X11 virtual desktop of a window.
- *
- * Results:
- * Virtual desktop number
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-UPWindowGetDesktop(UnityPlatform *up, // IN
- UnityPlatformWindow *upw, // IN
- int *guestDesktop) // IN/OUT
-{
- Atom propertyType;
- int propertyFormat;
- unsigned long itemsReturned = 0;
- unsigned long bytesRemaining;
- Atom *valueReturned = NULL;
- Bool retval = FALSE;
-
- if (!upw->clientWindow) {
- return FALSE;
- }
-
- if (XGetWindowProperty(up->display, upw->clientWindow,
- up->atoms._NET_WM_DESKTOP, 0,
- 1024, False, AnyPropertyType,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, (unsigned char **) &valueReturned)
- == Success
- && propertyType == XA_CARDINAL
- && propertyFormat == 32
- && itemsReturned) {
-
- *guestDesktop = *valueReturned;
- retval = TRUE;
- }
-
- XFree(valueReturned);
-
- return retval;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowUpdateDesktop --
- *
- * Updates the window's virtual desktop based on a new _NET_WM_DESKTOP attribute.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Notification to the window tracker.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowUpdateDesktop(UnityPlatform *up, // IN
- UnityPlatformWindow *upw) // IN
-{
- int guestDesktop = -1;
-
- if (!upw->clientWindow) {
- return;
- }
-
- if (!UPWindowGetDesktop(up, upw, &guestDesktop)) {
- Debug("Window %#lx has a clientWindow, but its "
- "virtual desktop could not be retrieved\n",
- upw->clientWindow);
- return;
- }
-
- if (guestDesktop < ((int)up->desktopInfo.numDesktops)) {
- UnityDesktopId desktopId = -1;
- Bool isSticky;
-
- isSticky = (guestDesktop < 0);
- if (!isSticky) {
- desktopId = up->desktopInfo.guestDesktopToUnity[guestDesktop];
- }
-
- Debug("Window %#lx is now on desktop %d\n", upw->toplevelWindow, desktopId);
- UnityWindowTracker_ChangeWindowDesktop(up->tracker,
- upw->toplevelWindow,
- desktopId);
-
- UnityWindowTracker_ChangeWindowAttribute(up->tracker,
- upw->toplevelWindow,
- UNITY_WINDOW_ATTR_STICKY,
- isSticky);
- } else {
- Debug("Guest's virtual desktop config may not match host's (yet?)"
- " (window is on desktop %d, guest is supposed to have %"FMTSZ"u desktops)\n",
- guestDesktop, up->desktopInfo.numDesktops);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowUpdateIcon --
- *
- * Updates the window's virtual desktop based on a new _NET_WM_DESKTOP attribute.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Notification to the window tracker.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowUpdateIcon(UnityPlatform *up, // IN
- UnityPlatformWindow *upw) // IN
-{
- UnityWindowTracker_NotifyIconChanged(up->tracker, upw->toplevelWindow,
- UNITY_ICON_TYPE_MAIN);
-
- if (DynBuf_GetSize(&upw->iconPng.data)) {
- DynBuf_SetSize(&upw->iconPng.data, 0);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowIsNowWithdrawn --
- *
- * In response to an update to a window's WM_STATE property, properties, test
- * whether or not the window has been withdrawn.
- *
- * Results:
- * TRUE if we believe the window was withdrawn, FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-UPWindowIsNowWithdrawn(UnityPlatform *up, // IN
- UnityPlatformWindow *upw, // IN
- const XPropertyEvent *xevent) // IN
-{
- Window mainWindow;
- Bool isWithdrawn = FALSE;
-
- Atom actual_type;
- int actual_format;
- unsigned long nitems;
- unsigned long bytes_remaining;
- unsigned char *properties = NULL;
-
- mainWindow = upw->clientWindow ? upw->clientWindow : upw->toplevelWindow;
-
- /*
- * Per ICCCM ยง4.1.3.1, WM_STATE.state will either be set to WithdrawnState
- * or WM_STATE removed from a window when it is withdrawn.
- */
- if (xevent->state == PropertyDelete) {
- return TRUE;
- }
-
- if (XGetWindowProperty(up->display, mainWindow, up->atoms.WM_STATE,
- 0, // offset
- 1, // length (in 32-bit chunks)
- False, // delete
- AnyPropertyType, // requested property type
- &actual_type, // returned type
- &actual_format, // returned format
- &nitems, // # of items returned
- &bytes_remaining, // # of bytes remaining
- &properties) == Success) {
- uint32 *state = (uint32 *)properties;
-
- if (actual_type == None ||
- (nitems > 0 && *state == WithdrawnState)) {
- isWithdrawn = TRUE;
- }
-
- XFree(properties);
- }
-
- return isWithdrawn;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowUpdateState --
- *
- * Tells the window tracker about the window's changes to the _NET_WM_STATE and
- * WM_STATE properties.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Notification to the window tracker
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowUpdateState(UnityPlatform *up, // IN
- UnityPlatformWindow *upw, // IN
- const XPropertyEvent *xevent) // IN
-{
- Atom propertyType;
- int propertyFormat;
- unsigned long itemsReturned;
- unsigned long bytesRemaining;
- Atom *valueReturned = NULL;
- uint i;
- Bool curAttrValues[UNITY_MAX_ATTRIBUTES];
- Bool attrsAreSet[UNITY_MAX_ATTRIBUTES];
- Bool isMinimized = FALSE;
- Bool haveHorizMax = FALSE;
- Bool haveVertMax = FALSE;
- Bool doSkipTaskbar = FALSE;
- Bool doSkipPager = FALSE;
- Window mainWindow;
-
- mainWindow = upw->clientWindow ? upw->clientWindow : upw->toplevelWindow;
-
- /*
- * If a change to WM_STATE indicates this window was withdrawn/unmapped, simply
- * invalidate it from the window tracker and return.
- */
- if (xevent->atom == up->atoms.WM_STATE &&
- UPWindowIsNowWithdrawn(up, upw, xevent)) {
- UPWindowSetRelevance(up, upw, FALSE);
- return;
- }
-
- memset(curAttrValues, 0, sizeof curAttrValues);
- memset(attrsAreSet, 0, sizeof attrsAreSet);
-
- curAttrValues[UNITY_WINDOW_ATTR_VISIBLE] = TRUE;
- attrsAreSet[UNITY_WINDOW_ATTR_VISIBLE] =
- attrsAreSet[UNITY_WINDOW_ATTR_MAXIMIZED] =
- attrsAreSet[UNITY_WINDOW_ATTR_STICKY] =
- attrsAreSet[UNITY_WINDOW_ATTR_ALWAYS_ABOVE] =
- attrsAreSet[UNITY_WINDOW_ATTR_ALWAYS_BELOW] =
- attrsAreSet[UNITY_WINDOW_ATTR_MODAL] =
- attrsAreSet[UNITY_WINDOW_ATTR_SHADED] =
- attrsAreSet[UNITY_WINDOW_ATTR_FULLSCREENED] =
- attrsAreSet[UNITY_WINDOW_ATTR_ATTN_WANTED] = TRUE;
-
- if (!UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_WM_STATE_HIDDEN)) {
- if (XGetWindowProperty(up->display, mainWindow, up->atoms.WM_STATE, 0,
- 1024, False, AnyPropertyType,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, (unsigned char **) &valueReturned)
- != Success) {
- /*
- * Some random error occurred - perhaps the window disappeared
- */
- return;
- }
-
- if (propertyType == up->atoms.WM_STATE
- && propertyFormat == 32
- && itemsReturned
- && valueReturned[0] == IconicState) {
- isMinimized = TRUE;
- }
- XFree(valueReturned);
- }
-
- if (XGetWindowProperty(up->display, mainWindow, up->atoms._NET_WM_STATE, 0,
- 1024, False, AnyPropertyType,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, (unsigned char **) &valueReturned)
- != Success) {
- /*
- * Some random error occurred - perhaps the window disappeared
- */
- return;
- }
-
- if (propertyType != XA_ATOM
- || propertyFormat != 32) {
- itemsReturned = 0;
- }
-
- for (i = 0; i < itemsReturned; i++) {
- UnityWindowAttribute attr;
- Bool attrValue = TRUE;
-
- if (valueReturned[i] == up->atoms._NET_WM_STATE_MINIMIZED
- || valueReturned[i] == up->atoms._NET_WM_STATE_HIDDEN) {
- isMinimized = TRUE;
- continue;
- } else if (valueReturned[i] == up->atoms._NET_WM_STATE_MAXIMIZED_HORZ) {
- haveHorizMax = TRUE;
- continue;
- } else if (valueReturned[i] == up->atoms._NET_WM_STATE_MAXIMIZED_VERT) {
- haveVertMax = TRUE;
- continue;
- } else if (valueReturned[i] == up->atoms._NET_WM_STATE_STICKY) {
- attr = UNITY_WINDOW_ATTR_STICKY;
- } else if (valueReturned[i] == up->atoms._NET_WM_STATE_ABOVE) {
- attr = UNITY_WINDOW_ATTR_ALWAYS_ABOVE;
- } else if (valueReturned[i] == up->atoms._NET_WM_STATE_BELOW) {
- attr = UNITY_WINDOW_ATTR_ALWAYS_BELOW;
- } else if (valueReturned[i] == up->atoms._NET_WM_STATE_MODAL) {
- attr = UNITY_WINDOW_ATTR_MODAL;
- } else if (valueReturned[i] == up->atoms._NET_WM_STATE_SHADED) {
- attr = UNITY_WINDOW_ATTR_SHADED;
- } else if (valueReturned[i] == up->atoms._NET_WM_STATE_FULLSCREEN) {
- attr = UNITY_WINDOW_ATTR_FULLSCREENED;
- } else if (valueReturned[i] == up->atoms._NET_WM_STATE_DEMANDS_ATTENTION) {
- attr = UNITY_WINDOW_ATTR_ATTN_WANTED;
- } else if (valueReturned[i] == up->atoms._NET_WM_STATE_SKIP_TASKBAR) {
- attr = UNITY_WINDOW_ATTR_TOOLWINDOW;
- doSkipTaskbar = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_WM_STATE_SKIP_PAGER) {
- doSkipPager = TRUE;
- continue;
- } else {
- continue;
- }
-
- curAttrValues[attr] = attrValue;
- attrsAreSet[attr] = TRUE;
- }
- XFree(valueReturned);
-
- curAttrValues[UNITY_WINDOW_ATTR_MAXIMIZED] = (haveHorizMax && haveVertMax);
- attrsAreSet[UNITY_WINDOW_ATTR_MAXIMIZED] = TRUE;
- curAttrValues[UNITY_WINDOW_ATTR_APPWINDOW] = (!doSkipPager && !doSkipTaskbar)
- && (upw->windowType == UNITY_WINDOW_TYPE_NORMAL);
- attrsAreSet[UNITY_WINDOW_ATTR_APPWINDOW] = TRUE;
-
- if (upw->isRelevant) {
- UnityWindowInfo *info;
- uint32 newState;
- int cDesk = -1;
- int gDesk;
-
- info = UnityWindowTracker_LookupWindow(up->tracker, upw->toplevelWindow);
- ASSERT(info);
-
- newState = info->state;
-
- /*
- * Only push minimize state for windows on the same desktop (inc. sticky
- * windows).
- */
- if (UPWindowGetDesktop(up, upw, &gDesk)) {
- cDesk = UnityX11GetCurrentDesktop(up);
- if (cDesk == gDesk || gDesk == -1) {
- if (isMinimized) {
- if (! (newState & UNITY_WINDOW_STATE_MINIMIZED)) {
- Debug("Enabling minimized attribute for window %#lx/%#lx\n",
- upw->toplevelWindow, upw->clientWindow);
- newState |= UNITY_WINDOW_STATE_MINIMIZED;
- }
- } else {
- if ((newState & UNITY_WINDOW_STATE_MINIMIZED)) {
- Debug("Disabling minimized attribute for window %#lx/%#lx\n",
- upw->toplevelWindow, upw->clientWindow);
- newState &= ~UNITY_WINDOW_STATE_MINIMIZED;
- }
- }
- }
- } else {
- Debug("%s: Unable to get window desktop\n", __FUNCTION__);
- }
-
- if (newState != info->state) {
- UnityWindowTracker_ChangeWindowState(up->tracker,
- upw->toplevelWindow,
- newState);
- }
-
- upw->isMinimized = isMinimized;
- upw->isMaximized = (haveHorizMax && haveVertMax);
-
- for (i = 0; i < UNITY_MAX_ATTRIBUTES; i++) {
- if (attrsAreSet[i]) {
- UnityWindowTracker_ChangeWindowAttribute(up->tracker, upw->toplevelWindow,
- (UnityWindowAttribute)i, curAttrValues[i]);
- }
- }
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowPushFullUpdate --
- *
- * Pushes a full update for the given window.
- *
- * Results:
- * TRUE if we pushed the updates for this window, FALSE otherwise.
- *
- * Side effects:
- * UnityWindowTracker contains latest info on this window.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-UPWindowPushFullUpdate(UnityPlatform *up, // IN
- UnityPlatformWindow *upw) // IN
-{
- XWindowAttributes winAttr;
- Atom *props;
- int propCount;
- int i;
- int x, y, xprime, yprime;
- int border_width;
-
- XGetWindowAttributes(up->display, upw->toplevelWindow, &winAttr);
- UPWindowUpdateFrameExtents(up, upw);
-
- x = winAttr.x;
- y = winAttr.y;
- border_width = winAttr.border_width;
-
- xprime = x + winAttr.width + border_width;
- yprime = y + winAttr.height + border_width;
- x -= border_width;
- y -= border_width;
-
- /*
- * If these are the same, then the window hasn't been reparented by
- * the window manager, and its window decorations are accounted for
- * by the values of the _NET_FRAME_EXTENTS property.
- */
- if (upw->toplevelWindow == upw->clientWindow) {
- x -= upw->frameExtents[0]; // left
- y -= upw->frameExtents[2]; // top
- xprime += upw->frameExtents[1]; // right
- yprime += upw->frameExtents[3]; // bottom
- }
-
- UnityWindowTracker_MoveWindow(up->tracker, upw->toplevelWindow,
- x, y, xprime, yprime);
-
-#if defined(VM_HAVE_X11_SHAPE_EXT)
- UPWindowUpdateShape(up, upw);
-#endif
- UPWindowUpdateType(up, upw);
-
- propCount = 0;
- UnityPlatformResetErrorCount(up);
- props = XListProperties(up->display,
- upw->clientWindow ? upw->clientWindow : upw->toplevelWindow,
- &propCount);
- if (!UnityPlatformGetErrorCount(up)) {
- for (i = 0; i < propCount; i++) {
- XEvent fakeEvent = {0,};
-
- fakeEvent.xproperty.state = PropertyNewValue;
- fakeEvent.xproperty.atom = props[i];
- UPWindowProcessPropertyEvent(up, upw, &fakeEvent);
- }
- XFree(props);
- }
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindow_ProtocolSupported --
- *
- * Returns whether a particular window supports a particular protocol.
- *
- * Results:
- * TRUE if supported, FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-UPWindow_ProtocolSupported(const UnityPlatform *up, // IN
- const UnityPlatformWindow *upw, // IN
- UnityX11WinProtocol proto) // IN
-{
- ASSERT(up);
- ASSERT(upw);
- ASSERT(proto < UNITY_X11_MAX_WIN_PROTOCOLS);
-
- return upw->windowProtocols[proto];
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformShowWindow --
- *
- * Makes hidden Window visible. If the Window is already visible, it stays
- * visible. Window reappears at its original location. A minimized window
- * reappears as minimized.
- *
- * Results:
- *
- * FALSE if the Window handle is invalid.
- * TRUE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformShowWindow(UnityPlatform *up, // IN
- UnityWindowId window) // IN
-{
- UnityPlatformWindow *upw;
-
- ASSERT(up);
-
- upw = UPWindow_Lookup(up, window);
-
- if (!upw || !upw->clientWindow) {
- Debug("Hiding FAILED!\n");
- return FALSE;
- }
-
- if (upw->isHidden) {
- Atom data[5] = {0, 0, 0, 0, 0};
-
- /*
- * Unfortunately the _NET_WM_STATE messages only work for windows that are already
- * mapped, i.e. not iconified or withdrawn.
- */
- if (!upw->isMinimized) {
- XMapRaised(up->display, upw->clientWindow);
- }
-
- data[0] = _NET_WM_STATE_REMOVE;
- data[1] = up->atoms._NET_WM_STATE_HIDDEN;
- data[3] = 2; // Message is from the pager/taskbar
- UnityPlatformSendClientMessage(up, upw->rootWindow, upw->clientWindow,
- up->atoms._NET_WM_STATE, 32, 4, data);
-
- upw->wantInputFocus = TRUE;
- upw->isHidden = FALSE;
- }
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformHideWindow --
- *
- * Hides window. If the window is already hidden it stays hidden. Hides
- * maximized and minimized windows too.
- *
- * Results:
- * FALSE if the Window handle is invalid.
- * TRUE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformHideWindow(UnityPlatform *up, // IN
- UnityWindowId window) // IN
-{
- UnityPlatformWindow *upw;
-
- ASSERT(up);
-
- upw = UPWindow_Lookup(up, window);
-
- if (!upw
- || !upw->clientWindow) {
- Debug("Hiding FAILED!\n");
- return FALSE;
- }
-
- if (!upw->isHidden) {
- Atom data[5] = {0, 0, 0, 0, 0};
-
- upw->isHidden = TRUE;
-
- data[0] = _NET_WM_STATE_ADD;
- data[1] = up->atoms._NET_WM_STATE_HIDDEN;
- data[3] = 2; // Message is from a pager/taskbar/etc.
- UnityPlatformSendClientMessage(up, upw->rootWindow, upw->clientWindow,
- up->atoms._NET_WM_STATE, 32, 4, data);
- }
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformMinimizeWindow --
- *
- * Mimimizes window. If the window is already mimimized it stays minimized.
- *
- * Results:
- * FALSE if the Window handle is invalid.
- * TRUE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformMinimizeWindow(UnityPlatform *up, // IN
- UnityWindowId window) // IN
-{
- UnityPlatformWindow *upw;
-
- ASSERT(up);
-
- upw = UPWindow_Lookup(up, window);
-
- if (!upw
- || !upw->clientWindow) {
- Debug("Minimizing FAILED!\n");
- return FALSE;
- }
-
- Debug("UnityPlatformMinimizeWindow(%#lx)\n", upw->toplevelWindow);
- upw->wantInputFocus = FALSE;
- if (!upw->isMinimized) {
- Atom data[5] = {0, 0, 0, 0, 0};
-
- Debug("Minimizing window %#x\n", window);
- upw->isMinimized = TRUE;
- data[0] = _NET_WM_STATE_ADD;
- if (UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_WM_STATE_MINIMIZED)) {
- data[1] = up->atoms._NET_WM_STATE_MINIMIZED;
- } else {
- data[1] = up->atoms._NET_WM_STATE_HIDDEN;
- }
- data[3] = 2; // Message is from a pager/taskbar/etc.
- UnityPlatformSendClientMessage(up, upw->rootWindow, upw->clientWindow,
- up->atoms._NET_WM_STATE, 32, 4, data);
-
- XIconifyWindow(up->display, upw->clientWindow, 0);
- } else {
- Debug("Window %#x is already minimized\n", window);
- }
-
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformMaximizeWindow --
- *
- * Maximizes window. If the window is already maximized it will stay so.
- *
- * Results:
- * FALSE if the Window handle is invalid.
- * TRUE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformMaximizeWindow(UnityPlatform *up, // IN
- UnityWindowId window) // IN
-{
- UnityPlatformWindow *upw;
-
- ASSERT(up);
-
- upw = UPWindow_Lookup(up, window);
-
- if (!upw
- || !upw->clientWindow) {
- Debug("Maximizing FAILED!\n");
- return FALSE;
- }
-
- if (!upw->isMaximized) {
- Atom data[5] = {0, 0, 0, 0, 0};
-
- upw->isMaximized = TRUE;
- data[0] = _NET_WM_STATE_ADD;
- data[1] = up->atoms._NET_WM_STATE_MAXIMIZED_HORZ;
- data[2] = up->atoms._NET_WM_STATE_MAXIMIZED_VERT;
- data[3] = 2; // Message is from a pager/taskbar/etc.
- UnityPlatformSendClientMessage(up, upw->rootWindow, upw->clientWindow,
- up->atoms._NET_WM_STATE, 32, 4, data);
- }
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformUnmaximizeWindow --
- *
- * Unmaximizes window. If the window is already unmaximized, it will stay
- * that way.
- *
- * Results:
- * FALSE if the Window handle is invalid.
- * TRUE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformUnmaximizeWindow(UnityPlatform *up, // IN
- UnityWindowId window) // IN
-{
- UnityPlatformWindow *upw;
-
- ASSERT(up);
-
- upw = UPWindow_Lookup(up, window);
-
- if (!upw
- || !upw->clientWindow) {
- Debug("Maximizing FAILED!\n");
- return FALSE;
- }
-
- if (upw->isMaximized) {
- Atom data[5] = {0, 0, 0, 0, 0};
-
- data[0] = _NET_WM_STATE_REMOVE;
- data[1] = up->atoms._NET_WM_STATE_MAXIMIZED_HORZ;
- data[2] = up->atoms._NET_WM_STATE_MAXIMIZED_VERT;
- data[3] = 2; // Message is from a pager/taskbar/etc.
- UnityPlatformSendClientMessage(up, upw->rootWindow, upw->clientWindow,
- up->atoms._NET_WM_STATE, 32, 4, data);
-
- upw->isMaximized = FALSE;
- }
-
- return TRUE;
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityPlatformSetWindowDesktop --
- *
- * Move the window to the specified desktop. The desktopId is an index
- * into the desktop configuration array.
- *
- * Results:
- * Returns TRUE if successful, and FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformSetWindowDesktop(UnityPlatform *up, // IN
- UnityWindowId windowId, // IN
- UnityDesktopId desktopId) // IN
-{
- UnityPlatformWindow *upw;
- uint32 guestDesktopId;
-
- ASSERT(up);
-
- upw = UPWindow_Lookup(up, windowId);
-
- if (!upw
- || !upw->clientWindow) {
- Debug("Desktop change FAILED on %#lx (perhaps it has no clientWindow)!\n",
- upw ? upw->toplevelWindow : 0);
- return FALSE;
- }
-
- /*
- * XXX I wrote this code assuming that UnityWindowTracker on the
- * guest side will be updated with the latest settings as they come
- * from the host, but that is not currently the case. unity.c needs
- * fixing.
- */
-
- ASSERT(desktopId < (int)up->desktopInfo.numDesktops);
- guestDesktopId = up->desktopInfo.unityDesktopToGuest[desktopId];
-
- UPWindow_SetEWMHDesktop(up, upw, guestDesktopId);
-
- return TRUE;
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UPWindow_SetEWMHDesktop --
- *
- * Move the window to the specified desktop. ewmhDesktopId corresponds
- * to a desktop index to be used with _NET_WM_DESKTOP.
- *
- * Results:
- * This will directly change _NET_WM_DESKTOP of an unmapped window,
- * and will instead request the window manager to update that property
- * for a mapped window.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-
-void
-UPWindow_SetEWMHDesktop(UnityPlatform *up, // IN
- UnityPlatformWindow *upw, // IN
- uint32 ewmhDesktopId) // IN
-{
- Atom data[5] = {0, 0, 0, 0, 0};
-
- ASSERT(up);
- ASSERT(upw);
-
- if (!upw->isViewable || upw->wantSetDesktopNumberOnUnmap) {
- Atom currentDesktop = ewmhDesktopId; // Cast for 64-bit correctness.
-
- /*
- * Sending the _NET_WM_DESKTOP client message only works if the
- * window is mapped. We should still send that message to
- * eliminate race conditions, but if the window is not mapped, we
- * also need to set the property on the window so that it shows
- * up on the correct desktop when it is re-mapped.
- *
- * wantSetDesktopNumberOnUnmap implies that we unmapped the window
- * in question. We evaluate this here, in addition to isViewable,
- * because it's totally possible that the window server processed
- * our unmap request, but we just haven't received the notification
- * yet. (In other words, if that's the case, isViewable may still
- * be TRUE.)
- */
-
- XChangeProperty(up->display, (Window)upw->clientWindow, up->atoms._NET_WM_DESKTOP,
- XA_CARDINAL, 32, PropModeReplace, (unsigned char *)¤tDesktop, 1);
- }
-
- data[0] = ewmhDesktopId;
- data[1] = 2; // Indicates that this was requested by the pager/taskbar/etc.
- UnityPlatformSendClientMessage(up,
- upw->rootWindow,
- upw->clientWindow,
- up->atoms._NET_WM_DESKTOP,
- 32, 5, data);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UPWindowUpdateFrameExtents --
- *
- * Lookup and record (cache) the _NET_FRAME_EXTENTS property.
- *
- * Results:
- * If _NET_FRAME_EXTENTS is set, upw->frameExtents may be updated.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UPWindowUpdateFrameExtents(UnityPlatform *up,
- UnityPlatformWindow *upw)
-{
- Atom propertyType;
- int propertyFormat = 0;
- unsigned long itemsReturned = 0;
- unsigned long bytesRemaining;
- unsigned char *valueReturned = NULL;
- Window w = upw->clientWindow ? upw->clientWindow : upw->toplevelWindow;
-
- ASSERT(up);
- ASSERT(upw);
-
- if (UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_FRAME_EXTENTS)
- && XGetWindowProperty(up->display, w, up->atoms._NET_FRAME_EXTENTS, 0,
- 1024, False, XA_CARDINAL,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, &valueReturned) == Success
- && propertyFormat == 32
- && itemsReturned >= 4) {
- Atom *atomValue = (Atom *)valueReturned;
-
- upw->frameExtents[0] = atomValue[0];
- upw->frameExtents[1] = atomValue[1];
- upw->frameExtents[2] = atomValue[2];
- upw->frameExtents[3] = atomValue[3];
-
- XFree(valueReturned);
- }
-}
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2010 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.
- *
- *********************************************************/
-
-/*
- * windowPathFactory.cc --
- *
- * Factory class which, given an X window ID, PID, or pathname tries to
- * find executable path and its corresponding "desktop entry" file. (See
- * http://standards.freedesktop.org/desktop-entry-spec/latest/.)
- *
- * TODO Isolated from UnityPlatform, this class looks up X atoms directly.
- * Will need to factor atom handling out from UnityPlatform and reconcile it
- * with this class.
- */
-
-#include <giomm/desktopappinfo.h>
-
-#include <fstream>
-#include <glibmm.h>
-
-#include "vmware/tools/unity/windowPathFactory.hh"
-
-extern "C" {
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <X11/Xmd.h>
-
-#include <gio/gdesktopappinfo.h>
-
-#undef Bool
-#include "vmware.h"
-#include "vmware/tools/utils.h"
-#include "posix.h"
-#include "str.h"
-#include "xdg.h"
-};
-
-namespace vmware {
-namespace tools {
-namespace unity {
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * WindowPathFactory::WindowPathFactory --
- *
- * Constructor.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-WindowPathFactory::WindowPathFactory(Display* dpy)
- : mDpy(dpy)
-{
- /*
- * PR631378 - see
- * http://standards.freedesktop.org/menu-spec/latest/ar01s04.html#menu-file-elements
- *
- * With OpenSUSE 11.2, apps under /usr/share/applications/kde4 are referred
- * to as kde4-$app, not just $app.
- */
- mEnvPrefixes.push_back("");
- mEnvPrefixes.push_back("gnome-");
- mEnvPrefixes.push_back("kde4-");
-
- /*
- * There isn't always a direct correspondance between an application's executable's
- * path and its .desktop file. For example on Ubuntu 10.10 Mozilla Firefox has a
- * firefox.desktop which launches "firefox". However "firefox" is just a symlink to
- * a wrapper around the actual Firefox executable, firefox-bin. It's the latter
- * which Unity/X11 will encounter and use as a starting point to find the app's
- * .desktop file.
- *
- * Below are pairs of regular expressions and candidate application names. If an
- * executable name matches pair.first(), we'll check for a pair.second()+".desktop".
- */
- // XXX Keep this in an external file.
-#define WPFADDMATCH(pattern, target) \
- mExecPatterns.push_back(std::make_pair(Glib::Regex::create(pattern), target))
- WPFADDMATCH("acroread$", "AdobeReader");
- WPFADDMATCH("firefox(-bin|$)", "firefox");
- WPFADDMATCH("firefox(-bin|$)", "mozilla-firefox");
- WPFADDMATCH("thunderbird(-bin|$)", "thunderbird");
- WPFADDMATCH("thunderbird(-bin|$)", "mozilla-thunderbird");
- WPFADDMATCH("soffice", "openoffice.org-base");
-#undef WPFADDMATCH
-
- // XXX Keep this in an external file.
- mSkipPatterns = Glib::Regex::create("^(sh|bash)-?|(perl|python)(-|\\d|$)");
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * WindowPathFactory::FindByXid --
- *
- * Search for executable and desktop entry based on an X11 window ID.
- *
- * Results:
- * Returns true and populates pathPair on success.
- * Returns false on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-bool
-WindowPathFactory::FindByXid(XID window, // IN
- WindowPathPair& pathPair) // OUT
-{
- bool success = false;
- int argc;
- char** argv;
- bool triedLeader = false;
- Window checkWindow = window;
-
-tryLeader:
- /*
- * We examine WM_COMMAND before checking argv because kdeinit has a tendency
- * to rewrite /proc/$pid/cmdline as "kdeinit4: foo [kdeinit] bar baz". Even
- * though it's deprecated, WM_COMMAND is widely available and specifies a
- * command vector suitable for launching an application from scratch.
- */
- if (XGetCommand(mDpy, checkWindow, &argv, &argc)) {
- std::vector<Glib::ustring> vec;
- for (int i = 0; i < argc; i++) {
- vec.push_back(argv[i]);
- }
- success = FindByArgv("" /* without a PID, cwd is unavailable */, vec,
- pathPair);
- XFreeStringList(argv);
- }
-
- pid_t windowPid;
- if ( !success
- && (windowPid = GetPidForXid(checkWindow)) != -1) {
- success = FindByPid(windowPid, pathPair);
- }
-
- if (!success && !triedLeader) {
- /*
- * Last ditch - look for a client leader window and try all of the above
- * again.
- */
- checkWindow = LookupClientLeader(window);
- if (checkWindow != None) {
- triedLeader = TRUE;
- goto tryLeader;
- }
- }
-
- return success;
-}
-
-
-/*
- ******************************************************************************
- * BEGIN Private member functions.
- */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * WindowPathFactory::CanonicalizeAppName --
- *
- * Turns the app name (or path) into a full path for the executable.
- *
- * Results:
- * Returns string of normalized path.
- *
- * Side effects:
- * None.
- *
- * TODO:
- * Deprecate AppUtil_CanonicalizeAppName.
- *
- *-----------------------------------------------------------------------------
- */
-
-Glib::ustring
-WindowPathFactory::CanonicalizeAppName(const Glib::ustring& appName, // IN
- const Glib::ustring& cwd) // IN
-{
- if (appName.empty()) {
- return Glib::ustring();
- } else if (appName[0] == '/') {
- return appName;
- }
-
- Glib::ustring tmp = Glib::find_program_in_path(appName);
- if (!tmp.empty()) {
- return tmp;
- }
-
- if (!cwd.empty()) {
- ASSERT(cwd[0] == '/');
-
- tmp = cwd + "/" + appName;
- char *ctmp = Posix_RealPath(tmp.c_str());
- if (ctmp) {
- tmp = ctmp;
- vm_free(ctmp);
- return tmp;
- }
- }
-
- return appName;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * WindowPathFactory::FindByArgv --
- *
- * Given an argument vector, guess which desktop entry fits best.
- *
- * Results:
- * Returns true and populates at least pathPair.first (executable path) on
- * success. Ideally will populate pathPair.second (desktop entry path),
- * too.
- * Returns false with pathPair unmodified on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-bool
-WindowPathFactory::FindByArgv(const Glib::ustring& cwd, // IN
- std::vector<Glib::ustring> argv, // IN
- WindowPathPair& pathPair) // OUT
-{
- std::vector<Glib::ustring>::iterator arg;
-
- /* Skip language interpreters. */
- for (arg = argv.begin(); arg != argv.end(); ++arg) {
- if (!IsSkippable(*arg)) {
- break;
- }
- }
-
- if (arg == argv.end()) {
- g_debug("%s: all args determined skippable.\n", __FUNCTION__);
- return false;
- }
-
- /* Examine our cache first. */
- ExecMap::const_iterator entry = mExecMap.find(*arg);
- if (entry != mExecMap.end()) {
- pathPair = entry->second;
- return true;
- }
-
- /* Given a presumable argv[0] and cwd, record the likely executable name. */
- pathPair.first = CanonicalizeAppName(*arg, cwd);
- pathPair.second = "";
-
- /*
- * Okay, arg may be absolute or relative.
- *
- * We'll search for a matching .desktop entry using the following methods:
- *
- * 1. Take the basename of arg and search for an application identified by
- * $arg.desktop.
- * 2. Consult static list of known applications and guess at possible
- * launchers. (firefox-bin => firefox, soffice.bin => ooffice.)
- */
-
- Glib::ustring testString = Glib::path_get_basename(*arg);
-
- std::vector<std::string> candidates;
- candidates.push_back(testString);
-
- for (std::vector<ExecPattern>::iterator pattern = mExecPatterns.begin();
- pattern != mExecPatterns.end();
- ++pattern) {
- if (pattern->first->match(testString)) {
- candidates.push_back(pattern->second);
- }
- }
-
- for (std::vector<std::string>::iterator candidate = candidates.begin();
- candidate != candidates.end();
- ++candidate)
- {
- for (std::vector<std::string>::iterator i = mEnvPrefixes.begin();
- i != mEnvPrefixes.end();
- ++i) {
- /* Try for a DesktopAppInfo identified by arg. */
- Glib::ustring desktopId =
- Glib::ustring::compose("%1%2.desktop", *i, *candidate);
- Glib::RefPtr<Gio::DesktopAppInfo> desktopApp =
- Gio::DesktopAppInfo::create(desktopId);
- if (desktopApp) {
- GDesktopAppInfo* gobj = desktopApp->gobj();
- pathPair.second = g_desktop_app_info_get_filename(gobj);
- mExecMap[*arg] = pathPair;
- return true;
- }
- }
- }
-
- /* Cache negative results. */
- mExecMap[*arg] = pathPair;
- return false;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * WindowPathFactory::FindByPid --
- *
- * Examine /proc/pid to find clues linking a process to a desktop entry.
- *
- * Results:
- * Returns true and populates desktopEntry on success.
- * Returns false on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-bool
-WindowPathFactory::FindByPid(pid_t pid, // IN
- WindowPathPair& pathPair) // OUT
-{
- /*
- * - Extract cwd, argv from /proc/pid/{cwd,cmdline}.
- * - Pass down to FindByArgv.
- */
-
- char cbuf[256];
- Str_Snprintf(cbuf, sizeof cbuf, "/proc/%d/cwd", pid);
-
- char cwdbuf[PATH_MAX];
- int i = readlink(cbuf, cwdbuf, sizeof cwdbuf);
- if (i <= 0) {
- /* Lookup of cwd failed. We'll try our best without it. */
- i = 0;
- }
- cwdbuf[i] = '\0';
-
- Str_Snprintf(cbuf, sizeof cbuf, "/proc/%d/cmdline", pid);
-
- try {
- std::vector<Glib::ustring> argv;
- std::ifstream ifstr(cbuf);
- std::string arg;
-
- while (ifstr.good()) {
- getline(ifstr, arg, '\0');
- if (!arg.empty()) {
- argv.push_back(arg);
- }
- }
-
- if (!argv.empty()) {
- return FindByArgv(Glib::ustring(cwdbuf), argv, pathPair);
- }
- } catch (std::exception& e) {
- g_warning("%s: Exception while parsing /proc/%d/cmdline: %s\n",
- __FUNCTION__, pid, e.what());
- }
-
- return false;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * WindowPathFactory::GetPidForXid --
- *
- * Given a window ID, query its _NET_WM_PID property to obtain its owning
- * PID.
- *
- * Results:
- * Returns a valid PID on success and -1 on failure.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-pid_t
-WindowPathFactory::GetPidForXid(XID window)
-{
- pid_t windowPid = -1;
-
- Atom pidAtom = XInternAtom(mDpy, "_NET_WM_PID", True);
- Atom propertyType;
-
- int ret;
- int propertyFormat;
- unsigned long itemsReturned = 0;
- unsigned long bytesRemaining;
- unsigned char *valueReturned = NULL;
- ret = XGetWindowProperty(mDpy, window, pidAtom, 0 /* offset */, 1024, False,
- AnyPropertyType, &propertyType, &propertyFormat,
- &itemsReturned, &bytesRemaining, &valueReturned);
- if (ret != Success) {
- return false;
- }
-
- if (propertyType == XA_CARDINAL && itemsReturned >= 1) {
- switch (propertyFormat) {
- case 16:
- windowPid = *(CARD16*)valueReturned;
- break;
- case 32:
- windowPid = *(XID*)valueReturned;
- break;
- default:
- g_warning("%s: Unknown propertyFormat %d while retrieving _NET_WM_PID\n",
- __FUNCTION__, propertyFormat);
- break;
- }
- }
- XFree(valueReturned);
-
- return windowPid;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * WindowPathFactory::IsSkippable --
- *
- * Primitive filter which returns true if an argument is a language
- * interpreter or similar executable not interesting to Unity/GHI.
- *
- * XXX This function was cribbed from AppUtil_IsAppSkippable. That function
- * and this one should eventually go away.
- *
- * Results:
- * Returns true if component is skippable, false otherwise.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-bool
-WindowPathFactory::IsSkippable(const Glib::ustring& component) // IN
-{
- Glib::ustring ctmp = Glib::path_get_basename(component);
- return mSkipPatterns->match(ctmp);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * WindowPathFactory::LookupClientLeader --
- *
- * Given a window ID, look up the associated "client leader" window,
- * identified by the WM_CLIENT_LEADER property, if it exists.
- *
- * Results:
- * A valid window ID if found, otherwise None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-XID
-WindowPathFactory::LookupClientLeader(XID window) // IN
-{
- Atom propertyType;
- int propertyFormat;
- unsigned long itemsReturned;
- unsigned long bytesRemaining;
- unsigned char *valueReturned = NULL;
-
- Atom findAtom = XInternAtom(mDpy, "WM_CLIENT_LEADER", True);
- Window leaderWindow = None;
-
- if ((XGetWindowProperty(mDpy, window, findAtom, 0, 4, False, XA_WINDOW,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, &valueReturned) == Success) &&
- propertyFormat == 32 && itemsReturned == 1) {
- leaderWindow = *(XID *)valueReturned;
- }
-
- XFree(valueReturned);
-
- return leaderWindow;
-}
-
-/*
- * END Private members functions.
- ******************************************************************************
- */
-
-} /* namespace unity */ } /*namespace tools */ } /* namespace vmware */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007-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.
- *
- *********************************************************/
-
-/**
- * @file x11Platform.cc
- *
- * Implementation of Unity for guest operating systems that use the X11 window
- * system. This file holds the basic things such as initialization/destruction
- * of the UnityPlatform object, overall event handling, and handling of some
- * Unity RPCs that are not window-centric.
- */
-
-#include "x11Platform.h"
-
-extern "C" {
-#include "appUtil.h"
-#include "region.h"
-#include <sys/time.h>
-
-#include <X11/extensions/Xinerama.h>
-#include <X11/extensions/XTest.h>
-
-#ifndef NO_XCOMPOSITE
-# include <X11/extensions/Xcomposite.h>
-#endif
-}
-
-typedef struct {
- Window realWindowID;
- XEvent xevent;
-} UnityTemporaryEvent;
-
-static UnitySpecialWindow *USWindowCreate(UnityPlatform *up,
- UnitySpecialEventHandler evHandler,
- Window *windows,
- int windowCount);
-static void USWindowUpdate(UnityPlatform *up,
- UnitySpecialWindow *usw,
- Window *windows,
- int windowCount);
-static UnitySpecialWindow *USWindowLookup(UnityPlatform *up, Window window);
-static void USWindowDestroy(UnityPlatform *up, UnitySpecialWindow *usw);
-
-static void UnityPlatformProcessXEvent(UnityPlatform *up,
- const XEvent *xevent,
- Window realEventWindow);
-static Window UnityPlatformGetRealEventWindow(UnityPlatform *up, const XEvent *xevent);
-static void USRootWindowsProcessEvent(UnityPlatform *up,
- UnitySpecialWindow *usw,
- const XEvent *xevent,
- Window window);
-static int UnityPlatformXErrorHandler(Display *dpy, XErrorEvent *xev);
-static UnitySpecialWindow *UnityPlatformMakeRootWindowsObject(UnityPlatform *up);
-
-static void UnityPlatformSendClientMessageFull(Display *d,
- Window destWindow,
- Window w,
- Atom messageType,
- int format,
- uint numItems,
- const void *data);
-static void UnityPlatformStackDnDDetWnd(UnityPlatform *up);
-static void UnityPlatformDnDSendClientMessage(UnityPlatform *up,
- Window destWindow,
- Window w,
- Atom messageType,
- int format,
- int numItems,
- const void *data);
-
-static Bool GetRelevantWMWindow(UnityPlatform *up,
- UnityWindowId windowId,
- Window *wmWindow);
-static Bool SetWindowStickiness(UnityPlatform *up,
- UnityWindowId windowId,
- Bool wantSticky);
-static UnitySpecialWindow *MakeCompositeOverlaysObject(UnityPlatform *up);
-
-/*
- * Has to be global for UnityPlatformXErrorHandler
- */
-static int unityX11ErrorCount = 0;
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformIsSupported --
- *
- * Determine whether this guest supports unity.
- *
- * Results:
- * TRUE if the guest supports Unity
- * FALSE otherwise
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformIsSupported(void)
-{
- Display *dpy;
- int major;
- int event_base;
- int error_base;
-
- dpy = GDK_DISPLAY();
- /*
- * Unity/X11 doesn't yet work with the new vmwgfx driver. Until that is
- * fixed, we have to disable the feature.
- *
- * As for detecting which driver is in use, the legacy driver provides the
- * VMWARE_CTRL extension for resolution and topology operations, while the
- * new driver is instead controlled via XRandR. If we don't find said
- * extension, then we'll assume the new driver is in use and disable Unity.
- */
- if (XQueryExtension(dpy, "VMWARE_CTRL", &major, &event_base, &error_base) ==
- False) {
- Debug("Unity is not yet supported under the vmwgfx driver.\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformInit --
- *
- * Initialize the UnityPlatform object that represents the platform-specific state.
- *
- * Results:
- * Pointer to newly allocated UnityPlatform data.
- *
- * Side effects:
- * No.
- *
- *----------------------------------------------------------------------------
- */
-
-UnityPlatform *
-UnityPlatformInit(UnityWindowTracker *tracker, // IN
- UnityHostCallbacks hostCallbacks) // IN:
-{
- UnityPlatform *up;
- char *displayName;
-
- ASSERT(tracker);
-
- Debug("UnityPlatformInit: Running\n");
-
- up = (UnityPlatform*)Util_SafeCalloc(1, sizeof *up);
- up->tracker = tracker;
- up->hostCallbacks = hostCallbacks;
-
- up->savedScreenSaverTimeout = -1;
-
- /*
- * Because GDK filters events heavily, and we need to do a lot of low-level X work, we
- * just open another connection to the same display.
- */
- displayName = gdk_get_display();
- up->display = XOpenDisplay(displayName);
- if (!up->display) {
- free(up);
- return NULL; // We couldn't connect to the display for some strange reason
- }
- XSetErrorHandler(UnityPlatformXErrorHandler);
- XSynchronize(up->display, TRUE); // So error counting works properly...
-
- /*
- * Certain applications, like gnome-session during logout, may grab the X
- * server before displaying a modal window. With the server grabbed, we're
- * unable to correctly track and display windows.
- *
- * The following snippet attempts to work around this by using the XTest
- * extension's ability to make ourselves impervious to X server grabs.
- */
- {
- int dummy1;
- int dummy2;
- int major;
- int minor;
-
- if ((XTestQueryExtension(up->display, &dummy1, &dummy2,
- &major, &minor) == True) &&
- ((major > 2) || (major == 2 && minor >= 2))) {
- if (XTestGrabControl(up->display, True) != 1) {
- Debug("XTestGrabControl failed.\n");
- }
- } else {
- Debug("XTest extension not available.\n");
- }
- }
-
- up->allWindows = HashTable_Alloc(128, HASH_INT_KEY, NULL);
- up->specialWindows = HashTable_Alloc(32, HASH_INT_KEY, NULL);
- up->desktopWindow = NULL;
- up->desktopInfo.initialDesktop = UNITY_X11_INITIALDESKTOP_UNSET;
-
- /*
- * Find the values of all the atoms
- */
-# define INIT_ATOM(x) up->atoms.x = XInternAtom(up->display, #x, False)
-
- INIT_ATOM(_NET_WM_WINDOW_TYPE);
- INIT_ATOM(_NET_WM_WINDOW_TYPE_DESKTOP);
- INIT_ATOM(_NET_WM_WINDOW_TYPE_DOCK);
- INIT_ATOM(_NET_WM_WINDOW_TYPE_TOOLBAR);
- INIT_ATOM(_NET_WM_WINDOW_TYPE_TOOLTIP);
- INIT_ATOM(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU);
- INIT_ATOM(_NET_WM_WINDOW_TYPE_POPUP_MENU);
- INIT_ATOM(_NET_WM_WINDOW_TYPE_MENU);
- INIT_ATOM(_NET_WM_WINDOW_TYPE_UTILITY);
- INIT_ATOM(_NET_WM_WINDOW_TYPE_SPLASH);
- INIT_ATOM(_NET_WM_WINDOW_TYPE_DIALOG);
- INIT_ATOM(_NET_WM_WINDOW_TYPE_NORMAL);
- INIT_ATOM(_NET_WM_WINDOW_TYPE_DND);
- INIT_ATOM(_NET_WM_STATE);
- INIT_ATOM(_NET_WM_STATE_HIDDEN);
- INIT_ATOM(_NET_WM_STATE_MODAL);
- INIT_ATOM(_NET_WM_STATE_STICKY);
- INIT_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
- INIT_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
- INIT_ATOM(_NET_WM_STATE_MINIMIZED);
- INIT_ATOM(_NET_WM_STATE_SHADED);
- INIT_ATOM(_NET_WM_STATE_SKIP_TASKBAR);
- INIT_ATOM(_NET_WM_STATE_SKIP_PAGER);
- INIT_ATOM(_NET_WM_STATE_FULLSCREEN);
- INIT_ATOM(_NET_WM_STATE_ABOVE);
- INIT_ATOM(_NET_WM_STATE_BELOW);
- INIT_ATOM(_NET_WM_STATE_DEMANDS_ATTENTION);
- INIT_ATOM(_NET_WM_USER_TIME);
- INIT_ATOM(_NET_WM_USER_TIME_WINDOW);
- INIT_ATOM(_NET_ACTIVE_WINDOW);
- INIT_ATOM(_NET_RESTACK_WINDOW);
- INIT_ATOM(_NET_WM_ICON);
- INIT_ATOM(_NET_WM_PID);
- INIT_ATOM(_NET_WM_STRUT);
- INIT_ATOM(_NET_WM_STRUT_PARTIAL);
- INIT_ATOM(_NET_MOVERESIZE_WINDOW);
- INIT_ATOM(_NET_CLOSE_WINDOW);
- INIT_ATOM(_NET_WM_ALLOWED_ACTIONS);
- INIT_ATOM(_NET_WM_ACTION_MOVE);
- INIT_ATOM(_NET_WM_ACTION_RESIZE);
- INIT_ATOM(_NET_WM_ACTION_MINIMIZE);
- INIT_ATOM(_NET_WM_ACTION_SHADE);
- INIT_ATOM(_NET_WM_ACTION_STICK);
- INIT_ATOM(_NET_WM_ACTION_MAXIMIZE_HORZ);
- INIT_ATOM(_NET_WM_ACTION_MAXIMIZE_VERT);
- INIT_ATOM(_NET_WM_ACTION_FULLSCREEN);
- INIT_ATOM(_NET_WM_ACTION_CHANGE_DESKTOP);
- INIT_ATOM(_NET_WM_ACTION_CLOSE);
- INIT_ATOM(_NET_NUMBER_OF_DESKTOPS);
- INIT_ATOM(_NET_WM_DESKTOP);
- INIT_ATOM(_NET_CURRENT_DESKTOP);
- INIT_ATOM(_NET_DESKTOP_LAYOUT);
- INIT_ATOM(_NET_SUPPORTED);
- INIT_ATOM(_NET_FRAME_EXTENTS);
- INIT_ATOM(WM_CLASS);
- INIT_ATOM(WM_CLIENT_LEADER);
- INIT_ATOM(WM_DELETE_WINDOW);
- INIT_ATOM(WM_ICON);
- INIT_ATOM(WM_NAME);
- INIT_ATOM(WM_PROTOCOLS);
- INIT_ATOM(WM_STATE);
- INIT_ATOM(WM_TRANSIENT_FOR);
- INIT_ATOM(WM_WINDOW_ROLE);
- INIT_ATOM(COMPOUND_TEXT);
- INIT_ATOM(UTF8_STRING);
-
-# undef INIT_ATOM
-
-#if defined(VM_HAVE_X11_SHAPE_EXT)
- if (!XShapeQueryExtension(up->display, &up->shapeEventBase, &up->shapeErrorBase)) {
- up->shapeEventBase = 0;
- }
-#endif
-
- up->wpFactory = new vmware::tools::unity::WindowPathFactory(up->display);
-
- return up;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformCleanup --
- *
- * One-time platform-specific cleanup code.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformCleanup(UnityPlatform *up) // IN
-{
- if (!up) {
- return;
- }
-
- /*
- * Caller should've called Unity_Exit first.
- */
- ASSERT(!up->isRunning);
- ASSERT(up->glibSource == NULL);
-
- delete up->wpFactory;
-
- if (up->specialWindows) {
- HashTable_Free(up->specialWindows);
- up->specialWindows = NULL;
- }
- if (up->allWindows) {
- HashTable_Free(up->allWindows);
- up->allWindows = NULL;
- }
-
- if (up->display) {
- XCloseDisplay(up->display);
- up->display = NULL;
- }
-
- up->desktopWindow = NULL;
-
- free(up);
-}
-
-
-/*****************************************************************************
- * Unity main loop and event handling *
- *****************************************************************************/
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * USWindowCreate --
- *
- * Creates a new UnitySpecialWindow. Ownership of the 'windows' memory is taken over
- * by the newly created object, but that memory MUST be malloc'd...
- *
- * Results:
- * New UnitySpecialWindow object.
- *
- * Side effects:
- * Allocates memory.
- *
- *-----------------------------------------------------------------------------
- */
-
-static UnitySpecialWindow *
-USWindowCreate(UnityPlatform *up, // IN
- UnitySpecialEventHandler evHandler, // IN
- Window *windows, // IN
- int windowCount) // IN
-{
- UnitySpecialWindow *usw;
-
- ASSERT(up);
-
- usw = (UnitySpecialWindow*)Util_SafeCalloc(1, sizeof *usw);
- usw->evHandler = evHandler;
- USWindowUpdate(up, usw, windows, windowCount);
-
- return usw;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * USWindowUpdate --
- *
- * Updates this USWindow with a new list of X windows. Ownership of the 'windows'
- * memory is taken over by this USWindow object. That memory MUST be malloc'd...
- *
- * Results:
- * None.
- *
- * Side effects:
- * Old window list may be destroyed and freed.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-USWindowUpdate(UnityPlatform *up, // IN
- UnitySpecialWindow *usw, // IN
- Window *windows, // IN
- int windowCount) // IN
-{
- ASSERT(up);
- ASSERT(usw);
-
- for (unsigned int i = 0; i < usw->numWindows; i++) {
- XSelectInput(up->display, usw->windows[i], 0);
- HashTable_Delete(up->specialWindows, GUINT_TO_POINTER(usw->windows[i]));
- }
-
- free(usw->windows);
- usw->windows = windows;
- usw->numWindows = windowCount;
-
- for (int i = 0; i < windowCount; i++) {
- HashTable_Insert(up->specialWindows, GUINT_TO_POINTER(windows[i]), usw);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * USWindowLookup --
- *
- * Looks up a special window
- *
- * Results:
- * UnitySpecialWindow object
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static UnitySpecialWindow *
-USWindowLookup(UnityPlatform *up, // IN
- Window window) // IN
-{
- UnitySpecialWindow *retval = NULL;
-
- HashTable_Lookup(up->specialWindows, GUINT_TO_POINTER(window), (void **)&retval);
-
- return retval;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * USWindowDestroy --
- *
- * Destroys a UnitySpecialWindow
- *
- * Results:
- * None.
- *
- * Side effects:
- * Memory is freed.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-USWindowDestroy(UnityPlatform *up, // IN
- UnitySpecialWindow *usw) // IN
-{
- ASSERT(up);
- ASSERT(usw);
-
- for (unsigned int i = 0; i < usw->numWindows; i++) {
- HashTable_Delete(up->specialWindows, GUINT_TO_POINTER(usw->windows[i]));
-
- if (usw->windowsAreOwned) {
- XDestroyWindow(up->display, usw->windows[i]);
- } else {
- /*
- * For now, assume we don't have any special windows that get extension events
- * and need a call like XScreenSaverSelectInput...
- */
- XSelectInput(up->display, usw->windows[i], 0);
- }
- }
- free(usw->windows);
-
- free(usw);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformMakeRootWindowsObject --
- *
- * Creates a UnitySpecialWindow to handle the root windows.
- *
- * Results:
- * UnitySpecialWindow
- *
- * Side effects:
- * Selects for events on the root windows.
- *
- *-----------------------------------------------------------------------------
- */
-
-static UnitySpecialWindow *
-UnityPlatformMakeRootWindowsObject(UnityPlatform *up) // IN
-{
- static const long eventMask =
- StructureNotifyMask
- | PropertyChangeMask
- | SubstructureNotifyMask
- | FocusChangeMask;
- int i;
- int numRootWindows;
- Window *rootWindows;
-
- ASSERT(up);
-
- numRootWindows = ScreenCount(up->display);
- ASSERT(numRootWindows > 0);
-
- rootWindows = (Window*)Util_SafeCalloc(numRootWindows, sizeof rootWindows[0]);
- for (i = 0; i < numRootWindows; i++) {
- rootWindows[i] = RootWindow(up->display, i);
- }
-
- for (i = 0; i < numRootWindows; i++) {
- XSelectInput(up->display, rootWindows[i], eventMask);
- }
-
- return USWindowCreate(up, USRootWindowsProcessEvent, rootWindows, numRootWindows);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformGetErrorCount --
- *
- * Retrieves the current count of X11 errors received by Unity.
- *
- * Results:
- * Current error count.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-int
-UnityPlatformGetErrorCount(UnityPlatform *up) // IN
-{
- return unityX11ErrorCount;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformResetErrorCount --
- *
- * Resets the Unity X11 error count to zero.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Error count reset.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformResetErrorCount(UnityPlatform *up) // IN
-{
- unityX11ErrorCount = 0;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformXErrorHandler --
- *
- * Handler for all X event errors.
- *
- * Results:
- * 1.
- *
- * Side effects:
- * Updates our X11 error counter.
- *
- *-----------------------------------------------------------------------------
- */
-
-static int
-UnityPlatformXErrorHandler(Display *dpy, // IN
- XErrorEvent *xev) // IN
-{
- char buf[1024];
- XGetErrorText(dpy, xev->error_code, buf, sizeof buf);
- Debug("> VMwareUserXErrorHandler: error %s on resource %#lx for request %d\n",
- buf, xev->resourceid, xev->request_code);
-
- unityX11ErrorCount++;
-
- return 1;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformGetServerTime --
- *
- * Returns an educated guess at the X server's current timestamp
- *
- * Results:
- * X server timestamp
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Time
-UnityPlatformGetServerTime(UnityPlatform *up) // IN
-{
- Time retval;
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- retval = up->eventTimeDiff + (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
-
- Debug("UserTime is guessed at %lu\n", retval);
-
- return retval;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * ComparePointers --
- *
- * Compares two pointers to see whether they're equal.
- *
- * Results:
- * -1, 0, or 1 (same meaning as strcmp return values)
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE int
-ComparePointers(const void *p1, // IN
- const void *p2) // IN
-{
- /*
- * Helper function for UnityPlatformKillHelperThreads
- */
- char** ptr1 = (char**)p1;
- char** ptr2 = (char**)p2;
- ptrdiff_t diff = (*ptr2 - *ptr1);
-
- if (diff < 0) {
- return -1;
- } else if (diff > 0) {
- return 1;
- }
-
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformExitUnity --
- *
- * Tears down the Unity "running" state.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Restores system settings.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformExitUnity(UnityPlatform *up) // IN
-{
- UnityPlatformWindow **upwList;
- UnitySpecialWindow **uswList;
- size_t i;
- size_t numWindows;
-
- if (!up || !up->isRunning) {
- ASSERT(up->glibSource == NULL);
- return;
- }
-
- UnityX11EventTeardownSource(up);
-
- up->desktopInfo.numDesktops = 0; // Zero means host has not set virtual desktop config
- free(up->desktopInfo.guestDesktopToUnity);
- up->desktopInfo.guestDesktopToUnity = NULL;
- free(up->desktopInfo.unityDesktopToGuest);
- up->desktopInfo.unityDesktopToGuest = NULL;
-
- UnityX11RestoreSystemSettings(up);
-
- HashTable_ToArray(up->allWindows,
- (void ***)&upwList,
- &numWindows);
- qsort(upwList, numWindows, sizeof *upwList, ComparePointers);
- for (i = 0; i < numWindows; i++) {
- if (i < (numWindows - 1) && upwList[i] == upwList[i + 1]) {
- continue;
- }
-
- UPWindow_Unref(up, upwList[i]);
- }
- free(upwList);
-
- up->workAreas = NULL;
- up->rootWindows = NULL;
- HashTable_ToArray(up->specialWindows,
- (void ***)&uswList,
- &numWindows);
- qsort(uswList, numWindows, sizeof *uswList, ComparePointers);
- for (i = 0; i < numWindows; i++) {
- if (i < (numWindows - 1) && uswList[i] == uswList[i + 1]) {
- continue;
- }
-
- USWindowDestroy(up, uswList[i]);
- }
- free(uswList);
-
- XSync(up->display, TRUE);
- up->desktopInfo.initialDesktop = UNITY_X11_INITIALDESKTOP_UNSET;
- up->isRunning = FALSE;
-
- Debug("Leaving unity mode\n");
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityX11GetWMProtocols --
- *
- * Updates the list of protocols supported by the window manager.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UnityX11GetWMProtocols(UnityPlatform *up) // IN
-{
- Atom propertyType;
- int propertyFormat;
- unsigned long itemsReturned;
- unsigned long bytesRemaining;
- Atom *valueReturned = NULL;
-
- ASSERT(up);
-
- memset(up->wmProtocols, 0, sizeof up->wmProtocols);
- if (XGetWindowProperty(up->display, up->rootWindows->windows[0],
- up->atoms._NET_SUPPORTED, 0,
- 1024, False, AnyPropertyType,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, (unsigned char **)&valueReturned)
- != Success) {
- return;
- }
-
- if ((propertyType == XA_ATOM || propertyType == XA_CARDINAL)
- && propertyFormat == 32) {
- unsigned long i;
-
- for (i = 0; i < itemsReturned; i++) {
- if (valueReturned[i] == up->atoms._NET_MOVERESIZE_WINDOW) {
- up->wmProtocols[UNITY_X11_WM__NET_MOVERESIZE_WINDOW] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_CLOSE_WINDOW) {
- up->wmProtocols[UNITY_X11_WM__NET_CLOSE_WINDOW] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_RESTACK_WINDOW) {
- up->wmProtocols[UNITY_X11_WM__NET_RESTACK_WINDOW] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_ACTIVE_WINDOW) {
- up->wmProtocols[UNITY_X11_WM__NET_ACTIVE_WINDOW] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_WM_ACTION_MINIMIZE) {
- up->wmProtocols[UNITY_X11_WM__NET_WM_ACTION_MINIMIZE] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_WM_ACTION_CLOSE) {
- up->wmProtocols[UNITY_X11_WM__NET_WM_ACTION_CLOSE] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_WM_ACTION_SHADE) {
- up->wmProtocols[UNITY_X11_WM__NET_WM_ACTION_SHADE] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_WM_ACTION_STICK) {
- up->wmProtocols[UNITY_X11_WM__NET_WM_ACTION_STICK] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_WM_ACTION_FULLSCREEN) {
- up->wmProtocols[UNITY_X11_WM__NET_WM_ACTION_FULLSCREEN] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_WM_ACTION_MAXIMIZE_HORZ) {
- up->wmProtocols[UNITY_X11_WM__NET_WM_ACTION_MAXIMIZE_HORZ] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_WM_ACTION_MAXIMIZE_VERT) {
- up->wmProtocols[UNITY_X11_WM__NET_WM_ACTION_MAXIMIZE_VERT] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_FRAME_EXTENTS) {
- up->wmProtocols[UNITY_X11_WM__NET_FRAME_EXTENTS] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_WM_STRUT_PARTIAL) {
- up->wmProtocols[UNITY_X11_WM__NET_WM_STRUT_PARTIAL] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_WM_STATE_HIDDEN) {
- up->wmProtocols[UNITY_X11_WM__NET_WM_STATE_HIDDEN] = TRUE;
- } else if (valueReturned[i] == up->atoms._NET_WM_STATE_MINIMIZED) {
- up->wmProtocols[UNITY_X11_WM__NET_WM_STATE_MINIMIZED] = TRUE;
- }
- }
- }
-
- XFree(valueReturned);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformEnterUnity --
- *
- * Start Unity running.
- *
- * Results:
- * TRUE if successful
- * FALSE otherwise
- *
- * Side effects:
- * Saves and changes system settings.
- * Starts watching for windowing system events.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformEnterUnity(UnityPlatform *up) // IN
-{
- UnityDesktopId activeDesktop;
-
- ASSERT(up);
- ASSERT(up->glibSource == NULL);
-
- XSync(up->display, TRUE);
- up->rootWindows = UnityPlatformMakeRootWindowsObject(up);
- MakeCompositeOverlaysObject(up);
- up->isRunning = TRUE;
- up->eventTimeDiff = 0;
-
- UnityX11SaveSystemSettings(up);
-
- UnityX11GetWMProtocols(up);
-
- if (up->desktopInfo.numDesktops == 0) {
- /*
- * PR 633099: Host UI hasn't set the desktop config yet. In that case,
- * let's go ahead and initialize our the host:guest desktop mappings
- * based on the guest's current configuration. (This avoids unnecessarily
- * changing the guest desktop layout.)
- *
- * XXX Consider factoring this out of UPSetDesktopConfig.
- */
- unsigned int i;
-
- ASSERT(up->desktopInfo.guestDesktopToUnity == NULL);
- ASSERT(up->desktopInfo.unityDesktopToGuest == NULL);
-
- up->desktopInfo.numDesktops = UnityPlatformGetNumVirtualDesktops(up);
- if (up->desktopInfo.numDesktops == 0) {
- Warning("%s: _NET_NUMBER_OF_DESKTOPS set to 0; impossible.\n", __FUNCTION__);
- return FALSE;
- }
-
- up->desktopInfo.guestDesktopToUnity = (UnityDesktopId*)
- Util_SafeMalloc(up->desktopInfo.numDesktops *
- sizeof up->desktopInfo.guestDesktopToUnity[0]);
- up->desktopInfo.unityDesktopToGuest = (uint32*)
- Util_SafeMalloc(up->desktopInfo.numDesktops *
- sizeof up->desktopInfo.unityDesktopToGuest[0]);
-
- for (i = 0; i < up->desktopInfo.numDesktops; i++) {
- up->desktopInfo.guestDesktopToUnity[i] =
- up->desktopInfo.unityDesktopToGuest[i] = i;
- }
- }
-
- UnityPlatformSyncDesktopConfig(up);
-
- if (up->desktopInfo.initialDesktop != UNITY_X11_INITIALDESKTOP_UNSET) {
- Debug("%s: Setting activeDesktop to initialDesktop (%u).\n", __func__,
- up->desktopInfo.initialDesktop);
- activeDesktop = up->desktopInfo.initialDesktop;
- } else {
- activeDesktop = UnityWindowTracker_GetActiveDesktop(up->tracker);
- }
- if (UnityPlatformSetDesktopActive(up, activeDesktop)) {;
- /*
- * XXX Rather than setting this directly here, should we instead wait for a
- * PropertyNotify event from the window manager to one of the root windows?
- * Doing so may be safer in that it confirms that our request was honored by
- * the window manager.
- */
- UnityWindowTracker_ChangeActiveDesktop(up->tracker, activeDesktop);
- }
-
- if (up->needWorkAreas) {
- /*
- * UNEXPECTED: The host called SetDesktopWorkArea before entering Unity mode, so we
- * need to go back and apply the remembered work area info.
- */
-
- UnityPlatformSetDesktopWorkAreas(up, up->needWorkAreas, up->needNumWorkAreas);
- free(up->needWorkAreas);
- up->needWorkAreas = NULL;
- }
-
- /*
- * Set up a callback in the glib main loop to listen for incoming X events on the
- * unity display connection.
- */
- UnityX11EventEstablishSource(up);
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformIsUnityRunning --
- *
- * Check to see if we are still in the unity mode.
- *
- * Results:
- * TRUE if we are in Unity mode
- * FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformIsUnityRunning(UnityPlatform *up) // IN
-{
- ASSERT(up);
-
- return up->isRunning;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformLock --
- *
- * Does nothing - our implementation is not threaded.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None (really).
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformLock(UnityPlatform *up) // IN
-{
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformUnlock --
- *
- * Does nothing - our implementation is not threaded.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformUnlock(UnityPlatform *up) // IN
-{
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformUpdateZOrder --
- *
- * Push the Z-Order of all windows into the window tracker.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-UnityPlatformUpdateZOrder(UnityPlatform *up) // IN
-{
- UnityWindowId *elements;
- size_t numElements;
- UnityPlatformWindow *curWindow;
-
- ASSERT(up);
- if (!up->stackingChanged) {
- return;
- }
-
- elements = (UnityWindowId*)alloca(UNITY_MAX_WINDOWS * sizeof elements[0]);
- for (numElements = 0, curWindow = up->topWindow;
- curWindow; curWindow = curWindow->lowerWindow) {
- if (curWindow->isRelevant) {
- elements[numElements++] = curWindow->toplevelWindow;
- }
- }
-
- UnityWindowTracker_SetZOrder(up->tracker,
- elements,
- numElements);
- up->stackingChanged = FALSE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformUpdateWindowState --
- *
- * Walk through /all/ the windows on the guest, pushing everything we know about
- * them into the unity window tracker.
- *
- * Results:
- * TRUE indicating we need help from the common code to generate
- * remove window events (see unity.c)
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformUpdateWindowState(UnityPlatform *up, // IN
- UnityWindowTracker *tracker) // IN
-{
- unsigned int curRoot;
- Window lowerWindow = None;
-
- if (!up || !up->rootWindows) {
- Debug("BUG: UpdateWindowState was called before we are fully in Unity mode...\n");
- return FALSE;
- }
-
- for (curRoot = 0; curRoot < up->rootWindows->numWindows; curRoot++) {
- unsigned int i;
- Window dummyWin;
- Window *children;
- unsigned int numChildren;
-
- XQueryTree(up->display, up->rootWindows->windows[curRoot],
- &dummyWin, &dummyWin, &children, &numChildren);
-
- for (i = 0; i < numChildren; i++) {
- UnityPlatformWindow *upw;
-
- if (!HashTable_Lookup(up->allWindows,
- GUINT_TO_POINTER(children[i]),
- (void **)&upw)) {
- upw = UPWindow_Create(up, children[i]);
- if (!upw) {
- continue; // Window may have disappeared since the XQueryTree
- }
- UPWindow_CheckRelevance(up, upw, NULL);
- UPWindow_Restack(up, upw, lowerWindow);
- }
-
- lowerWindow = upw->toplevelWindow;
- }
-
- XFree(children);
- }
-
- UnityPlatformUpdateZOrder(up);
- /*
- * up is not populated with the window layout structure when
- * UnityPlatformUpdateDnDDetWnd is intially called.
- */
- UnityPlatformStackDnDDetWnd(up);
-
- if (up->needTaskbarSetting) {
- up->needTaskbarSetting = FALSE;
- /*
- * This is called in this seemingly random spot to make sure that the taskbar
- * visibility is properly set once we have a full picture of the windowing system
- * state. Although the routine is called prior to this by SaveSystemSettings(), the
- * up->allWindows hash table is not complete until this point, which occurs at a
- * random time of the host's choosing.
- */
- UnityPlatformSetTaskbarVisible(up, up->currentSettings[UNITY_UI_TASKBAR_VISIBLE]);
- }
-
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityX11HandleEvents --
- *
- * Handle incoming events
- *
- * Results:
- * TRUE if the main loop should continue watching for events from the display.
- *
- * Side effects:
- * Events read from the X display and processed.
- *
- *-----------------------------------------------------------------------------
- */
-
-gboolean
-UnityX11HandleEvents(gpointer data) // IN
-{
- UnityPlatform *up = (UnityPlatform *) data;
- GList *incomingEvents = NULL;
- Bool restackDetWnd = FALSE;
-
- ASSERT(up);
- ASSERT(up->isRunning);
-
- while (XEventsQueued(up->display, QueuedAfterFlush)) {
- /*
- * This outer loop is here to make sure we really process all available events
- * before returning.
- */
-
- while (XEventsQueued(up->display, QueuedAlready)) {
- UnityTemporaryEvent *ev;
-
- ev = (UnityTemporaryEvent*)Util_SafeCalloc(1, sizeof *ev);
- XNextEvent(up->display, &ev->xevent);
- ev->realWindowID = UnityPlatformGetRealEventWindow(up, &ev->xevent);
-
- /*
- * Restack dnd detection window when either
- * 1. the desktop window may overlap detection window, or
- * 2. a window is inserted directly above the desktop (and therefore
- * below the DND window).
- */
- if (up->desktopWindow &&
- ev->xevent.type == ConfigureNotify &&
- (up->desktopWindow->toplevelWindow == ev->realWindowID ||
- up->desktopWindow->toplevelWindow == ev->xevent.xconfigure.above)) {
- restackDetWnd = TRUE;
- }
-
- if (ev->xevent.type == DestroyNotify) {
- /*
- * Unfortunately, X's event-driven model has an inherent race condition for
- * parties that are observing events on windows that are controlled by other
- * applications. Basically, if we're processing an event on a window, that
- * window may have already been destroyed, and there doesn't seem to really
- * be a way to detect this. We just have to try to cut down the probability
- * of those as much as possible, by discarding any events on a window if
- * they're immediately followed by a DestroyNotify on the same window...
- */
- GList *curItem;
- GList *nextItem = NULL;
-
- for (curItem = incomingEvents; curItem; curItem = nextItem) {
- UnityTemporaryEvent *otherEvent = (UnityTemporaryEvent*)curItem->data;
- nextItem = curItem->next;
-
- if (otherEvent->realWindowID == ev->realWindowID) {
- free(curItem->data);
- incomingEvents = g_list_remove_link(incomingEvents, curItem);
- }
- }
- }
-
- incomingEvents = g_list_append(incomingEvents, ev);
- }
-
- while (incomingEvents) {
- GList *nextItem;
- UnityTemporaryEvent *tempEvent = (UnityTemporaryEvent*)incomingEvents->data;
-
- UnityPlatformProcessXEvent(up, &tempEvent->xevent, tempEvent->realWindowID);
-
- nextItem = incomingEvents->next;
- free(incomingEvents->data);
- g_list_free_1(incomingEvents);
- incomingEvents = nextItem;
- }
-
- if (restackDetWnd) {
- UnityPlatformStackDnDDetWnd(up);
- }
- UnityPlatformUpdateZOrder(up);
- UnityPlatformDoUpdate(up, TRUE);
- }
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformGetEventString --
- *
- * Allows stringifying events for debugging purposes
- *
- * Results:
- * A stringified version of the event name. It's a static value - do not free this.
- *
- * Side effects:
- * None.
- *-----------------------------------------------------------------------------
- */
-
-const char *
-UnityPlatformGetEventString(UnityPlatform *up, // IN
- int type) // IN
-{
-#if defined(VM_HAVE_X11_SHAPE_EXT)
- if (up->shapeEventBase
- && type == (up->shapeEventBase + ShapeNotify)) {
- return "ShapeNotify";
- }
-#endif
-
- switch (type) {
- case KeyPress: return "KeyPress";
- case KeyRelease: return "KeyRelease";
- case ButtonPress: return "ButtonPress";
- case ButtonRelease: return "ButtonRelease";
- case MotionNotify: return "MotionNotify";
- case EnterNotify: return "EnterNotify";
- case LeaveNotify: return "LeaveNotify";
- case FocusIn: return "FocusIn";
- case FocusOut: return "FocusOut";
- case KeymapNotify: return "KeymapNotify";
- case Expose: return "Expose";
- case GraphicsExpose: return "GraphicsExpose";
- case NoExpose: return "NoExpose";
- case VisibilityNotify: return "VisibilityNotify";
- case CreateNotify: return "CreateNotify";
- case DestroyNotify: return "DestroyNotify";
- case UnmapNotify: return "UnmapNotify";
- case MapNotify: return "MapNotify";
- case MapRequest: return "MapRequest";
- case ReparentNotify: return "ReparentNotify";
- case ConfigureNotify: return "ConfigureNotify";
- case ConfigureRequest: return "ConfigureRequest";
- case GravityNotify: return "GravityNotify";
- case ResizeRequest: return "ResizeRequest";
- case CirculateNotify: return "CirculateNotify";
- case CirculateRequest: return "CirculateRequest";
- case PropertyNotify: return "PropertyNotify";
- case SelectionClear: return "SelectionClear";
- case SelectionRequest: return "SelectionRequest";
- case SelectionNotify: return "SelectionNotify";
- case ColormapNotify: return "ColormapNotify";
- case ClientMessage: return "ClientMessage";
- case MappingNotify: return "MappingNotify";
- default: return "<Unknown>";
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformGetRealEventWindow --
- *
- * For debugging purposes, retrieves the window that the event happened on (as
- * opposed to the window the event was sent to)
- *
- * Results:
- * The window that the event actually happened on.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Window
-UnityPlatformGetRealEventWindow(UnityPlatform *up, // IN
- const XEvent *xevent) // IN
-{
-#if defined(VM_HAVE_X11_SHAPE_EXT)
- if (up->shapeEventBase
- && xevent->type == (up->shapeEventBase + ShapeNotify)) {
- XShapeEvent *sev = (XShapeEvent *) xevent;
-
- return sev->window;
- }
-#endif
-
- switch (xevent->type) {
- case CreateNotify:
- return xevent->xcreatewindow.window;
-
- case DestroyNotify:
- return xevent->xdestroywindow.window;
-
- case MapNotify:
- return xevent->xmap.window;
-
- case UnmapNotify:
- return xevent->xunmap.window;
-
- case ReparentNotify:
- return xevent->xreparent.window;
-
- case ConfigureNotify:
- return xevent->xconfigure.window;
-
- case CirculateNotify:
- return xevent->xcirculate.window;
-
- case PropertyNotify:
- return xevent->xproperty.window;
-
- case FocusIn:
- case FocusOut:
- return xevent->xfocus.window;
-
- default:
- return xevent->xany.window;
-
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformUpdateEventTimeDiff --
- *
- * Updates our idea of the difference between X server time and our local time.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Updated event time diff.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UnityPlatformUpdateEventTimeDiff(UnityPlatform *up, // IN
- const XEvent *xevent) // IN
-{
- Time serverTime;
- Time localTime;
- struct timeval localTv;
-
- switch (xevent->type) {
- case KeyPress:
- case KeyRelease:
- serverTime = xevent->xkey.time;
- break;
- case ButtonPress:
- case ButtonRelease:
- serverTime = xevent->xbutton.time;
- break;
- case MotionNotify:
- serverTime = xevent->xmotion.time;
- break;
- case EnterNotify:
- case LeaveNotify:
- serverTime = xevent->xcrossing.time;
- break;
- case PropertyNotify:
- serverTime = xevent->xproperty.time;
- break;
- case SelectionClear:
- serverTime = xevent->xselectionclear.time;
- break;
- case SelectionRequest:
- serverTime = xevent->xselectionrequest.time;
- break;
- case SelectionNotify:
- serverTime = xevent->xselection.time;
- break;
-
- default:
- return;
- }
-
- gettimeofday(&localTv, NULL);
- localTime = (localTv.tv_sec * 1000) + (localTv.tv_usec / 1000); // Convert to ms
- up->eventTimeDiff = serverTime - localTime;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformProcessXEvent --
- *
- * Processes an incoming X event.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May create or destroy UnityPlatformWindow objects.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UnityPlatformProcessXEvent(UnityPlatform *up, // IN
- const XEvent *xevent, // IN
- Window realEventWindow) // IN
-{
- UnityPlatformWindow *upw = NULL;
- const char *eventName;
-
- ASSERT(up);
- ASSERT(xevent);
-
- UnityPlatformUpdateEventTimeDiff(up, xevent);
-
- eventName = UnityPlatformGetEventString(up, xevent->type);
- upw = UPWindow_Lookup(up, realEventWindow);
- if (!upw) {
- UnitySpecialWindow *usw = USWindowLookup(up, realEventWindow);
- if (usw) {
- if (usw->evHandler) {
- usw->evHandler(up, usw, xevent, realEventWindow);
- }
-
- return;
- } else if (xevent->type == CreateNotify) {
- /* Ignore decoration widgets. They'll be reparented later. */
- if (UnityX11Util_IsWindowDecorationWidget(up, realEventWindow)) {
- Debug("%s: Window %#lx is a decoration widget. Ignore it.\n",
- __func__, realEventWindow);
- return;
- }
-
- /*
- * It may be a new window that we don't know about yet. Let's create an object
- * to track it.
- */
- upw = UPWindow_Create(up, realEventWindow);
- if (upw) {
- UPWindow_CheckRelevance(up, upw, NULL);
- } else {
- Debug("UnityX11ThreadProcessEvent BOMBED:"
- " %s on window %#lx (reported to %#lx)\n",
- eventName, realEventWindow, xevent->xany.window);
- }
- } else {
- /*
- * If we use them on non-CreateNotify events, the above lines of code wind up
- * trying to create objects for crazy windows that don't exist...
- */
- Debug("Ignoring %s event on unknown window %#lx (reported to %#lx)\n",
- eventName, realEventWindow, xevent->xany.window);
- }
- }
-
- if (upw) {
- UPWindow_ProcessEvent(up, upw, realEventWindow, xevent);
- if (upw->deleteWhenSafe) {
- Debug("%s: refs %u, deleteWhenSafe %u\n", __func__, upw->refs,
- upw->deleteWhenSafe);
- UPWindow_Unref(up, upw);
- }
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformIsRootWindow --
- *
- * Checks whether a given window ID is the root window. Necessary because each
- * screen has a separate root window, which makes checking a little more complicated
- * than ==.
- *
- * Results:
- * TRUE if the given window is a root window, FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformIsRootWindow(UnityPlatform *up, // IN
- Window window) // IN
-{
- ASSERT(up);
-
- return (USWindowLookup(up, window) == up->rootWindows);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityX11SetCurrentDesktop --
- *
- * Sets the active virtual desktop.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Changes the virtual desktop.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityX11SetCurrentDesktop(UnityPlatform *up, // IN
- uint32 currentDesktop) // IN: guest-side desktop ID
-{
- Atom data[5] = {0,0,0,0,0};
-
- ASSERT(up);
- ASSERT(up->rootWindows->windows);
-
- up->desktopInfo.currentDesktop = currentDesktop;
- data[0] = currentDesktop;
- data[1] = UnityPlatformGetServerTime(up);
- UnityPlatformSendClientMessage(up,
- up->rootWindows->windows[0],
- up->rootWindows->windows[0],
- up->atoms._NET_CURRENT_DESKTOP,
- 32, 5, data);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityX11GetCurrentDesktop --
- *
- * Gets the active virtual desktop.
- *
- * Results:
- * The active virtual desktop. If it cannot be retrieved for any reason, a
- * reasonable default of '0' will be returned.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-uint32
-UnityX11GetCurrentDesktop(UnityPlatform *up) // IN
-{
- Atom propertyType;
- int propertyFormat;
- unsigned long itemsReturned;
- unsigned long bytesRemaining;
- Atom *valueReturned;
- uint32 currentDesktop;
-
- ASSERT(up);
- ASSERT(up->rootWindows);
-
- if (XGetWindowProperty(up->display, up->rootWindows->windows[0],
- up->atoms._NET_CURRENT_DESKTOP, 0,
- 1024, False, AnyPropertyType,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, (unsigned char **)&valueReturned)
- == Success
- && propertyType == XA_CARDINAL
- && propertyFormat == 32) {
- ASSERT(itemsReturned == 1);
-
- currentDesktop = valueReturned[0];
- } else {
- currentDesktop = 0;
- }
- XFree(valueReturned);
-
- return currentDesktop;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * USRootWindowsUpdateCurrentDesktop --
- *
- * Looks at the root window to figure out the current desktop
- *
- * Results:
- * None.
- *
- * Side effects:
- * Updates UnityWindowTracker.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-USRootWindowsUpdateCurrentDesktop(UnityPlatform *up, // IN
- UnitySpecialWindow *usw, // IN
- Window window) // IN
-{
- uint32 currentDesktop;
- UnityDesktopId unityDesktop;
-
- /*
- * XXX right now this is going to break if there are multiple screens in the guest,
- * since each one can have an independant 'current' desktop...
- */
-
- ASSERT(up);
- currentDesktop = UnityX11GetCurrentDesktop(up);
-
- if (currentDesktop >= up->desktopInfo.numDesktops) {
- Warning("Active desktop is out of range for some strange reason\n");
- currentDesktop = 0;
- }
-
- unityDesktop = up->desktopInfo.guestDesktopToUnity[currentDesktop];
- Debug("%s: currentDesktop %u, unityDesktop %u\n", __func__, currentDesktop, unityDesktop);
- UnityWindowTracker_ChangeActiveDesktop(up->tracker, unityDesktop);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * USRootWindowsProcessEvent --
- *
- * Processes an event that occurred on one of the root windows.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-USRootWindowsProcessEvent(UnityPlatform *up, // IN
- UnitySpecialWindow *usw, // IN
- const XEvent *xevent, // IN
- Window window) // IN
-{
-
- /*
- * XXX Do we need to handle situations where the root window changes size? Any other
- * properties?
- */
- switch (xevent->type) {
- case PropertyNotify:
- if (xevent->xproperty.atom == up->atoms._NET_CURRENT_DESKTOP) {
- USRootWindowsUpdateCurrentDesktop(up, usw, window);
- } else if (xevent->xproperty.atom == up->atoms._NET_NUMBER_OF_DESKTOPS) {
- size_t numDesktops;
-
- numDesktops = UnityPlatformGetNumVirtualDesktops(up);
- if (numDesktops != up->desktopInfo.numDesktops) {
- UnityPlatformSyncDesktopConfig(up);
- }
- } else if (xevent->xproperty.atom == up->atoms._NET_DESKTOP_LAYOUT) {
- Atom layoutData[4];
-
- UnityPlatformGetVirtualDesktopLayout(up, layoutData);
- if (memcmp(layoutData, up->desktopInfo.layoutData, sizeof layoutData) != 0) {
- UnityPlatformSyncDesktopConfig(up);
- }
- }
- break;
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformWMProtocolSupported --
- *
- * Returns whether the window manager supports a particular protocol.
- *
- * Results:
- * TRUE if the protocol is supported, FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformWMProtocolSupported(UnityPlatform *up, // IN
- UnityX11WMProtocol proto) // IN
-{
- ASSERT(up);
- ASSERT(proto < UNITY_X11_MAX_WM_PROTOCOLS);
-
- return up->wmProtocols[proto];
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformSendClientMessageFull --
- *
- * Sends an XSendEvent.
- *
- * Results:
- *
- * Side effects:
- *
- *----------------------------------------------------------------------------
- */
-
-
-static void
-UnityPlatformSendClientMessageFull(Display *d, // IN
- Window destWindow, // IN: Window to send msg to
- Window w, // IN: What the msg's "To:"
- // header should be, so to speak.
- Atom messageType, // IN
- int format, // IN
- uint numItems, // IN
- const void *data) // IN
-{
- XClientMessageEvent ev;
- uint i;
-
- memset(&ev, 0, sizeof ev);
- ev.type = ClientMessage;
- ev.window = w;
- ev.message_type = messageType;
- ev.format = format;
- switch (format) {
- case 8:
- ASSERT(numItems <= ARRAYSIZE(ev.data.b));
- for (i = 0; i < numItems; i++) {
- const char *datab = (const char*)data;
- ev.data.b[i] = datab[i];
- }
- break;
- case 16:
- ASSERT(numItems <= ARRAYSIZE(ev.data.s));
- for (i = 0; i < numItems; i++) {
- const short *datas = (const short*)data;
- ev.data.s[i] = datas[i];
- }
- break;
- case 32:
- ASSERT(numItems <= ARRAYSIZE(ev.data.l));
- for (i = 0; i < numItems; i++) {
- const Atom *datal = (const Atom*)data;
- ev.data.l[i] = datal[i];
- }
- break;
- }
- if (! XSendEvent(d, destWindow, False,
- PropertyChangeMask|SubstructureRedirectMask|SubstructureNotifyMask, (XEvent *)&ev)) {
- Debug("XSendEvent failed\n");
- }
-}
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformSendClientMessage --
- *
- * Sends an XClientMessageEvent (such as one of the _NET_WM messages)
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformSendClientMessage(UnityPlatform *up, // IN
- Window destWindow, // IN: Window to actually send msg to
- Window w, // IN: What the msg's "To:" header
- // should be, so to speak.
- Atom messageType, // IN
- int format, // IN
- int numItems, // IN
- const void *data) // IN
-{
- UnityPlatformSendClientMessageFull(up->display, destWindow, w, messageType,
- format, numItems, data);
-}
-
-
-/*****************************************************************************
- * Misc Unity RPCs that need to be handled *
- *****************************************************************************/
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformSetTopWindowGroup --
- *
- * Set the group of windows on top of all others.
- *
- * Results:
- * TRUE if success,
- * FALSE otherwise.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformSetTopWindowGroup(UnityPlatform *up, // IN: Platform data
- UnityWindowId *windows, // IN: array of window ids
- unsigned int windowCount) // IN: # of windows in the array
-{
- Window sibling = None;
- uint i;
-
- ASSERT(up);
- ASSERT(windows);
- ASSERT(windowCount);
-
- /*
- * Restack everything bottom to top.
- */
- for (i = 0; i < windowCount; i++) {
- UnityPlatformWindow *upw;
- Window curWindow;
- Atom data[5] = {0,0,0,0,0};
-
- upw = UPWindow_Lookup(up, windows[i]);
- if (!upw) {
- continue;
- }
-
- curWindow = upw->clientWindow ? upw->clientWindow : upw->toplevelWindow;
- UPWindow_SetUserTime(up, upw);
-
- if (UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_RESTACK_WINDOW)) {
- data[0] = 2; // Magic source indicator to give full control
- data[1] = sibling;
- data[2] = Above;
-
- UnityPlatformSendClientMessage(up, up->rootWindows->windows[0],
- curWindow,
- up->atoms._NET_RESTACK_WINDOW,
- 32, 5, data);
- } else {
- XWindowChanges winch = {0,};
- winch.stack_mode = Above;
- winch.sibling = sibling;
- unsigned int valueMask = CWStackMode;
-
- if (sibling != None) {
- valueMask |= CWSibling;
- }
-
- /*
- * As of writing, Metacity doesn't support _NET_RESTACK_WINDOW and
- * will block our attempt to raise a window unless it's active, so
- * we activate the window first.
- */
- if (UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_ACTIVE_WINDOW)) {
- data[0] = 2; // Magic source indicator to give full control
- data[1] = UnityPlatformGetServerTime(up);
- data[2] = None;
- UnityPlatformSendClientMessage(up, up->rootWindows->windows[0],
- curWindow,
- up->atoms._NET_ACTIVE_WINDOW,
- 32, 5, data);
- }
-
- XReconfigureWMWindow(up->display, upw->toplevelWindow, 0, valueMask, &winch);
- }
-
- sibling = upw->toplevelWindow;
- }
-
- XSync(up->display, False);
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformDnDSendClientMessage --
- *
- * XXX This is a hack because UnityPlatformSendClientMessage doesn't work
- * for dnd windows.
- * Sends an XClientMessageEvent (such as one of the _NET_WM messages)
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-UnityPlatformDnDSendClientMessage(UnityPlatform *up, // IN
- Window destWindow, // IN: Window to send msg to
- Window w, // IN: What the msg's "To:"
- // header should be, so to speak.
- Atom messageType, // IN
- int format, // IN
- int numItems, // IN
- const void *data) // IN
-{
- UnityPlatformSendClientMessageFull(GDK_DISPLAY(), destWindow, w,
- messageType, format, numItems, data);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * UnityPlatformStackDnDDetWnd --
- *
- * Updates the stacking order of the dnd detection window.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-UnityPlatformStackDnDDetWnd(UnityPlatform *up)
-{
- static const Atom onDesktop[] = { 0xFFFFFFFF, 0, 0, 0, 0 };
-
- if (!up->dnd.setMode || !up->dnd.detWnd) {
- Debug("%s: DnD not yet initialized.\n", __func__);
- return;
- }
-
- if (!up->desktopWindow) {
- Debug("Desktop Window not cached. Tracker isn't populated.\n");
- return;
- }
-
- /* Show the window on every desktop. */
- UnityPlatformDnDSendClientMessage(up,
- up->rootWindows->windows[0],
- GDK_WINDOW_XWINDOW(up->dnd.detWnd->window),
- up->atoms._NET_WM_DESKTOP,
- 32, 5, onDesktop);
-
- if (up->desktopWindow) {
- XWindowChanges ch;
- XSetWindowAttributes sa;
- Window desktop = up->desktopWindow->toplevelWindow;
-
- /* Prevent the window manager from managing our detection window. */
- sa.override_redirect = True;
- XChangeWindowAttributes(GDK_DISPLAY(),
- GDK_WINDOW_XWINDOW(up->dnd.detWnd->window),
- CWOverrideRedirect, &sa);
-
- /* Resize and restack the detection window. */
- ch.x = 0;
- ch.y = 0;
- ch.width = 65535;
- ch.height = 65535;
- ch.sibling = desktop;
- ch.stack_mode = Above;
-
- XConfigureWindow(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(up->dnd.detWnd->window),
- CWX|CWY|CWWidth|CWHeight|CWStackMode | CWSibling, &ch);
-
- Debug("Restacking dnd detection window.\n");
- } else {
- /*
- * Attempt to rely on window manager if we cannot find a window to stack
- * above.
- */
- Atom position[] = { _NET_WM_STATE_ADD,
- up->atoms._NET_WM_STATE_STICKY,
- up->atoms._NET_WM_STATE_BELOW, 0, 0 };
-
- Debug("Unable to locate desktop window to restack detection window above.\n");
- UnityPlatformDnDSendClientMessage(up,
- up->rootWindows->windows[0],
- GDK_WINDOW_XWINDOW(up->dnd.detWnd->window),
- up->atoms._NET_WM_STATE,
- 32, 5, position);
- XMoveResizeWindow(GDK_DISPLAY(),
- GDK_WINDOW_XWINDOW(up->dnd.detWnd->window),
- 0, 0, 65535, 65535);
- }
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityPlatformUpdateDnDDetWnd --
- *
- * Shows/hides a full-screen drag detection wnd for unity guest->host DnD.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-void
-UnityPlatformUpdateDnDDetWnd(UnityPlatform *up, // IN
- Bool show) // IN
-{
-
- if (!up || !up->dnd.setMode || !up->dnd.detWnd) {
- /*
- * This function may potentially be called during UnityPlatform destruction.
- */
- return;
- }
-
- if (show) {
- gtk_widget_show(up->dnd.detWnd);
- UnityPlatformStackDnDDetWnd(up);
- Debug("Showing dnd detection window.\n");
- } else {
- gtk_widget_hide(up->dnd.detWnd);
- Debug("Hiding dnd detection window.\n");
- }
-
- up->dnd.setMode(show);
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityPlatformSetActiveDnDDetWnd --
- *
- * Set current full-screen drag detection wnd. The caller retains ownership
- * of the data. The caller is responsible for updating the active dnd det
- * wnd.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-void
-UnityPlatformSetActiveDnDDetWnd(UnityPlatform *up, // IN
- UnityDnD *data) // IN
-{
- up->dnd = *data;
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityPlatformSetDesktopWorkAreas --
- *
- * Sets the work areas for all screens.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformSetDesktopWorkAreas(UnityPlatform *up, // IN
- UnityRect workAreas[], // IN
- uint32 numWorkAreas) // IN
-{
- int iScreens;
- uint i;
- XineramaScreenInfo *screenInfo = NULL;
- int numScreens;
- RegionPtr strutsRegion;
- RegionPtr screenRegion;
- RegionPtr workAreasRegion;
- XID (*strutInfos)[12];
- uint numStrutInfos;
-
- if (!up->rootWindows) {
- /*
- * We're not in Unity mode yet. Save the info until we are.
- */
-
- up->needWorkAreas = (UnityRect*)Util_SafeMalloc(numWorkAreas * sizeof *up->needWorkAreas);
- memcpy(up->needWorkAreas, workAreas, numWorkAreas * sizeof *up->needWorkAreas);
- up->needNumWorkAreas = numWorkAreas;
- return TRUE;
- }
-
- if (!UnityPlatformWMProtocolSupported(up, UNITY_X11_WM__NET_WM_STRUT_PARTIAL)) {
- Debug("Window manager does not support _NET_WM_STRUT_PARTIAL - not setting desktop work area.\n");
- return FALSE;
- }
-
- ASSERT(up);
- ASSERT(up->rootWindows);
-
- /*
- * Get the geometry of all attached screens. If we're running multi-mon,
- * we'll query the Xinerama extension. Otherwise we just fall back to
- * examining our root window's geometry.
- */
- int q;
- if (XineramaQueryExtension(up->display, &q, &q)) {
- screenInfo = XineramaQueryScreens(up->display, &numScreens);
- }
-
- if (!screenInfo) {
- int32 rootX;
- int32 rootY;
- uint rootWidth;
- uint rootHeight;
- uint dummy;
- Window winDummy;
-
- if (numWorkAreas > 1) {
- Debug("Xinerama extension not present, or XineramaQueryScreens failed,"
- " but multiple work areas were requested.\n");
- return FALSE;
- }
-
- if (!XGetGeometry(up->display, up->rootWindows->windows[0], &winDummy,
- &rootX, &rootY, &rootWidth, &rootHeight,
- &dummy, &dummy)) {
- return FALSE;
- }
-
- screenInfo = (XineramaScreenInfo*)Util_SafeCalloc(1, sizeof *screenInfo);
- numScreens = 1;
-
- screenInfo->x_org = rootX;
- screenInfo->y_org = rootY;
- screenInfo->width = rootWidth;
- screenInfo->height = rootHeight;
- }
-
- if ((uint32)numScreens != numWorkAreas) {
- Warning("Mismatch between host-specified work areas and available "
- "screens. Request dropped.\n");
- free(screenInfo);
- return FALSE;
- }
-
- /*
- * New and improved wild'n'crazy scheme to map the host's work area
- * coordinates to a collection of struts.
- *
- * This implementation depends upon the y-x banded rectangles
- * implementation of lib/region.
- *
- * In short, here's how things go:
- *
- * 1. For each Xinerama screen (or the root window in case we have no
- * Xinerama) and host work area, a region is created. A strut
- * region is then created by subtracting the work area region from
- * the screen region.
- *
- * 2. This remaining region will contain between 0 and 4 rectangles,
- * each of which will be transformed into a strut window.
- *
- * For each of these rectangles, we infer based on their dimensions
- * which screen boundary the resulting strut should be bound to.
- *
- * a. Boxes touching both the left and right sides of the screen
- * are either top or bottom struts, depending on whether they
- * also touch the top or bottom edge.
- *
- * b. Any remaining box will touch either the left OR the right
- * side, but not both. (Such an irregular layout cannot be
- * described by the work areas RPC.) That box's strut will
- * then be attached to the same side of the screen.
- *
- * While also not perfect, this algorithm should do a better job of creating
- * struts along their correct sides of a screen than its predecessor. It
- * will let us assume the common case that what we define as a strut attached
- * to the left or right side really should be attached to the left or right,
- * rather than attached to the top or bottom and spanning the height of the
- * display.
- *
- * Pathological case:
- * 1. Screen geometry: 1280x960.
- * Left strut: 100px wide, 600px tall. Touches top of screen.
- * Right strut: 1180px wide, 100px tall. Touches top of screen.
- *
- * 2. Note that these struts touch each other. We'd interpret the resulting
- * work area as follows:
- *
- * Top strut: 1280px wide, 100px tall.
- * Left strut: 100px wide, 500px tall, starting from y = 100.
- *
- * I believe this sort of layout to be uncommon enough that we can accept
- * failure here. If we -really- want to get these things right, then
- * we should send strut information explicitly, rather than having the
- * guest try to deduce it from work area geometry.
- */
-
- /*
- * One strut per screen edge = at most 4 strutInfos.
- */
- strutInfos = (XID(*)[12])alloca(4 * sizeof *strutInfos * numScreens);
- memset(strutInfos, 0, 4 * sizeof *strutInfos * numScreens);
- numStrutInfos = 0;
-
- for (iScreens = 0; iScreens < numScreens; iScreens++) {
- int iRects;
-
- xRectangle screenRect;
- xRectangle workAreaRect;
-
- /*
- * Steps 1a. Create screen, work area regions.
- */
- screenRect.x = screenInfo[iScreens].x_org;
- screenRect.y = screenInfo[iScreens].y_org;
- screenRect.width = screenInfo[iScreens].width;
- screenRect.height = screenInfo[iScreens].height;
- screenRect.info.type = UpdateRect;
-
- workAreaRect.x = workAreas[iScreens].x;
- workAreaRect.y = workAreas[iScreens].y;
- workAreaRect.width = workAreas[iScreens].width;
- workAreaRect.height = workAreas[iScreens].height;
- workAreaRect.info.type = UpdateRect;
-
- screenRegion = miRectsToRegion(1, &screenRect, 0);
- workAreasRegion = miRectsToRegion(1, &workAreaRect, 0);
-
- /*
- * Step 1b. Create struts region by subtracting work area from screen.
- */
- strutsRegion = miRegionCreate(NULL, 0);
- miSubtract(strutsRegion, screenRegion, workAreasRegion);
- miRegionDestroy(workAreasRegion);
- miRegionDestroy(screenRegion);
-
- /*
- * Step 2. Transform struts region rectangles into individual struts.
- */
- for (iRects = 0; iRects < REGION_NUM_RECTS(strutsRegion);
- iRects++, numStrutInfos++) {
- BoxPtr p = REGION_RECTS(strutsRegion) + iRects;
- int bounds = 0;
-#define TOUCHES_LEFT 0x1
-#define TOUCHES_RIGHT 0x2
-#define TOUCHES_TOP 0x4
-#define TOUCHES_BOTTOM 0x8
-
- if (p->x1 == screenRect.x) { bounds |= TOUCHES_LEFT; }
- if (p->x2 == screenRect.x + screenRect.width) { bounds |= TOUCHES_RIGHT; }
- if (p->y1 == screenRect.y) { bounds |= TOUCHES_TOP; }
- if (p->y2 == screenRect.y + screenRect.height) { bounds |= TOUCHES_BOTTOM; }
-
- /*
- * strutInfos is passed directly to
- * XSetProperty(..._NET_WM_STRUTS_PARTIAL). I.e., look up that
- * property's entry in NetWM/wm-spec for more info on the indices.
- *
- * I went the switch/case route only because it does a better job
- * (for me) of organizing & showing -all- possible cases. YMMV.
- *
- * The region code treats rectanges as ranges from [x1,x2) and
- * [y1,y2). In other words, x2 and y2 are OUTSIDE the region. I
- * guess it makes calculating widths/heights easier. However, the
- * strut width/height dimensions are INCLUSIVE, so we'll subtract 1
- * from the "end" (as opposed to "start") value.
- *
- * (Ex: A 1600x1200 display with a 25px top strut would be marked
- * as top = 25, top_start_x = 0, top_end_x = 1599.)
- */
- switch (bounds) {
- case TOUCHES_LEFT | TOUCHES_RIGHT | TOUCHES_TOP:
- /* Top strut. */
- strutInfos[numStrutInfos][2] = p->y2 - p->y1;
- strutInfos[numStrutInfos][8] = p->x1;
- strutInfos[numStrutInfos][9] = p->x2 - 1;
- break;
- case TOUCHES_LEFT | TOUCHES_RIGHT | TOUCHES_BOTTOM:
- /* Bottom strut. */
- strutInfos[numStrutInfos][3] = p->y2 - p->y1;
- strutInfos[numStrutInfos][10] = p->x1;
- strutInfos[numStrutInfos][11] = p->x2 - 1;
- break;
- case TOUCHES_LEFT:
- case TOUCHES_LEFT | TOUCHES_TOP:
- case TOUCHES_LEFT | TOUCHES_BOTTOM:
- case TOUCHES_LEFT | TOUCHES_TOP | TOUCHES_BOTTOM:
- /* Left strut. */
- strutInfos[numStrutInfos][0] = p->x2 - p->x1;
- strutInfos[numStrutInfos][4] = p->y1;
- strutInfos[numStrutInfos][5] = p->y2 - 1;
- break;
- case TOUCHES_RIGHT:
- case TOUCHES_RIGHT | TOUCHES_TOP:
- case TOUCHES_RIGHT | TOUCHES_BOTTOM:
- case TOUCHES_RIGHT | TOUCHES_TOP | TOUCHES_BOTTOM:
- /* Right strut. */
- strutInfos[numStrutInfos][1] = p->x2 - p->x1;
- strutInfos[numStrutInfos][6] = p->y1;
- strutInfos[numStrutInfos][7] = p->y2 - 1;
- break;
- case TOUCHES_LEFT | TOUCHES_RIGHT | TOUCHES_TOP | TOUCHES_BOTTOM:
- Warning("%s: Struts occupy entire display.", __func__);
- /* FALLTHROUGH */
- default:
- Warning("%s: Irregular strut configuration: bounds %4x\n", __func__, bounds);
- miRegionDestroy(strutsRegion);
- goto out;
- break;
- }
- }
-#undef TOUCHES_LEFT
-#undef TOUCHES_RIGHT
-#undef TOUCHES_TOP
-#undef TOUCHES_BOTTOM
-
- miRegionDestroy(strutsRegion);
- }
-
- /*
- * The first step is making sure we have enough windows in existence to list the
- * _NET_WM_STRUT_PARTIAL properties for each screen.
- */
- if (!up->workAreas
- || up->workAreas->numWindows != numStrutInfos) {
- Window *newWinList;
-
- newWinList = (Window*)Util_SafeCalloc(numStrutInfos, sizeof *newWinList);
- if (up->workAreas) {
- memcpy(newWinList, up->workAreas->windows,
- MIN(numStrutInfos, up->workAreas->numWindows) * sizeof *newWinList);
- }
-
- /*
- * Destroy unneeded windows
- */
- for (i = numStrutInfos; i < (up->workAreas ? up->workAreas->numWindows : 0); i++) {
- XDestroyWindow(up->display, up->workAreas->windows[i]);
- }
-
- /*
- * Create additional windows as needed.
- */
- for (i = up->workAreas ? up->workAreas->numWindows : 0; i < numStrutInfos; i++) {
- static const char strutWindowName[] = "vmware-user workarea struts";
- Atom allDesktops = -1;
- newWinList[i] = XCreateWindow(up->display, up->rootWindows->windows[0],
- -50, -50, 1, 1, 0, CopyFromParent, InputOnly,
- CopyFromParent, 0, NULL);
- XChangeProperty(up->display, newWinList[i], up->atoms._NET_WM_WINDOW_TYPE,
- XA_ATOM, 32, PropModeReplace,
- (unsigned char *)&up->atoms._NET_WM_WINDOW_TYPE_DOCK, 1);
- XChangeProperty(up->display, newWinList[i], up->atoms._NET_WM_DESKTOP,
- XA_CARDINAL, 32, PropModeReplace,
- (unsigned char *)&allDesktops, 1);
- XStoreName(up->display, newWinList[i], strutWindowName);
- XMapWindow(up->display, newWinList[i]);
- }
-
- if (up->workAreas) {
- USWindowUpdate(up, up->workAreas, newWinList, numStrutInfos);
- } else {
- up->workAreas = USWindowCreate(up, NULL, newWinList, numStrutInfos);
- up->workAreas->windowsAreOwned = TRUE;
- }
- }
-
- /*
- * Now actually set the _NET_WM_STRUT_PARTIAL property on our special 'struts'
- * windows.
- */
- for (i = 0; i < numStrutInfos; i++) {
- Window strutWindow;
-
- strutWindow = up->workAreas->windows[i];
-
- XChangeProperty(up->display, strutWindow, up->atoms._NET_WM_STRUT_PARTIAL, XA_CARDINAL,
- 32, PropModeReplace, (unsigned char *)strutInfos[i], ARRAYSIZE(strutInfos[i]));
- }
-
-out:
- free(screenInfo);
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformGetNumVirtualDesktops --
- *
- * Retrieves the number of virtual desktops currently set in the guest.
- *
- * Results:
- * Number of desktops.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-size_t
-UnityPlatformGetNumVirtualDesktops(UnityPlatform *up) // IN
-{
- Atom propertyType;
- int propertyFormat;
- unsigned long itemsReturned;
- unsigned long bytesRemaining;
- Atom *valueReturned;
- size_t retval;
-
- ASSERT(up);
- if (XGetWindowProperty(up->display, up->rootWindows->windows[0],
- up->atoms._NET_NUMBER_OF_DESKTOPS, 0,
- 1024, False, AnyPropertyType,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, (unsigned char **)&valueReturned)
- == Success
- && propertyType == XA_CARDINAL
- && propertyFormat == 32) {
- ASSERT(itemsReturned == 1);
-
- retval = valueReturned[0];
- } else {
- retval = 1;
- }
- XFree(valueReturned);
-
- return retval;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformGetVirtualDesktopLayout --
- *
- * Retrieves the guest's current virtual desktop layout info, and stores it in
- * 'layoutData' (an array of 4 Atoms).
- *
- * Results:
- * Desktop layout stored in 'layoutData'
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformGetVirtualDesktopLayout(UnityPlatform *up, // IN
- Atom *layoutData) // OUT
-{
- Atom propertyType;
- int propertyFormat;
- unsigned long itemsReturned;
- unsigned long bytesRemaining;
- Atom *valueReturned;
-
- ASSERT(up);
-
- layoutData[3] = _NET_WM_TOPLEFT;
- if (XGetWindowProperty(up->display, up->rootWindows->windows[0],
- up->atoms._NET_DESKTOP_LAYOUT, 0,
- 1024, False, AnyPropertyType,
- &propertyType, &propertyFormat, &itemsReturned,
- &bytesRemaining, (unsigned char **)&valueReturned)
- == Success
- && propertyType == XA_CARDINAL
- && propertyFormat == 32) {
- ASSERT(itemsReturned == 3 || itemsReturned == 4);
-
- memcpy(layoutData,
- valueReturned,
- itemsReturned * sizeof *valueReturned);
- } else {
- layoutData[0] = _NET_WM_ORIENTATION_HORZ;
- layoutData[1] = 0;
- layoutData[2] = 1;
- }
- XFree(valueReturned);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformSyncDesktopConfig --
- *
- * This routine takes the virtual desktop configuration stored in UnityPlatform and
- * makes sure that the guest's actual virtual desktop configuration matches. This is
- * done in three situations:
- * 1. Updating the guest's virtual desktop config to match the host's, right after
- * the host's virtual desktop config has changed.
- * 2. Forcing the guest's virtual desktop config back to the host's, right after
- * the user uses the guest's pager to alter the guest virtual desktop config.
- * 3. Restoring the guest's virtual desktop configuration when exiting Unity mode.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Guest windows may jump to different virtual desktops if desktops are removed.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformSyncDesktopConfig(UnityPlatform *up) // IN
-{
- Atom data[5] = {0, 0, 0, 0, 0};
-
- ASSERT(up);
-
- if (!up->rootWindows || !up->display) {
- return; // This function might be called while not in Unity mode
- }
-
- data[0] = up->desktopInfo.numDesktops;
- UnityPlatformSendClientMessage(up,
- up->rootWindows->windows[0],
- up->rootWindows->windows[0],
- up->atoms._NET_NUMBER_OF_DESKTOPS,
- 32, 5,
- data);
- XChangeProperty(up->display, up->rootWindows->windows[0],
- up->atoms._NET_DESKTOP_LAYOUT, XA_CARDINAL,
- 32, PropModeReplace, (unsigned char *)up->desktopInfo.layoutData, 4);
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityPlatformSetDesktopConfig --
- *
- * Set the virtual desktop configuration as specified by the host.
- *
- * Results:
- * Returns TRUE if successful, and FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformSetDesktopConfig(UnityPlatform *up, // IN
- const UnityVirtualDesktopArray *desktopConfig) // IN
-{
- uint i;
- int x;
- int y;
- UnityVirtualDesktop minDesktop;
- UnityVirtualDesktop maxDesktop;
- UnityVirtualDesktop desktopSpread;
- int unityDesktopLayout[MAX_VIRT_DESK][MAX_VIRT_DESK];
- int guestDesktopLayout[MAX_VIRT_DESK][MAX_VIRT_DESK];
-
- ASSERT(up);
- ASSERT(desktopConfig);
- ASSERT(desktopConfig->desktopCount >= 1);
-
- /*
- * This long section of code mainly exists to verify that the host's virtual desktop
- * setup can be represented on our end, and to figure out how best to do it. We could
- * do this simply, if we didn't have to deal with the possibility of having 5 virtual
- * desktops in a 3x2 layout, which is a very real possibility on Linux hosts...
- */
- memset(unityDesktopLayout, 0xFF, sizeof unityDesktopLayout); // Set all entries to -1
- minDesktop = desktopConfig->desktops[0];
- maxDesktop = minDesktop;
- for (i = 1; i < desktopConfig->desktopCount; i++) {
- if (desktopConfig->desktops[i].x < minDesktop.x) {
- minDesktop.x = desktopConfig->desktops[i].x;
- }
- if (desktopConfig->desktops[i].y < minDesktop.y) {
- minDesktop.y = desktopConfig->desktops[i].y;
- }
- if (desktopConfig->desktops[i].x > maxDesktop.x) {
- maxDesktop.x = desktopConfig->desktops[i].x;
- }
- if (desktopConfig->desktops[i].y > maxDesktop.y) {
- maxDesktop.y = desktopConfig->desktops[i].y;
- }
- }
- desktopSpread.x = maxDesktop.x - minDesktop.x;
- desktopSpread.y = maxDesktop.y - minDesktop.y;
-
- for (i = 0; i < desktopConfig->desktopCount; i++) {
- int32 localX = desktopConfig->desktops[i].x - minDesktop.x;
- int32 localY = desktopConfig->desktops[i].y - minDesktop.y;
-
- if (localY >= MAX_VIRT_DESK || localX >= MAX_VIRT_DESK) {
- Warning("Unity virtual desktop layout has holes that are too big to handle\n");
- return FALSE;
- }
-
- unityDesktopLayout[localX][localY] = i;
- }
-
- for (x = 0; x < desktopSpread.x; x++) {
- for (y = 0; y < desktopSpread.y; y++) {
- if (unityDesktopLayout[x][y] < 0) {
- Warning("Unity virtual desktop layout has holes that we can't handle.\n");
- return FALSE;
- }
- }
- }
-
- /*
- * Check along the left edge to make sure that there aren't any gaps between virtual
- * desktops.
- */
- for (x = desktopSpread.x, y = 0; y <= desktopSpread.y; y++) {
- if (unityDesktopLayout[x][y] < 0) {
- break;
- }
- }
- for (; y <= desktopSpread.y; y++) {
- if (unityDesktopLayout[x][y] >= 0) {
- Warning("Unity virtual desktop layout has holes along the right edge.\n");
- return FALSE;
- }
- }
-
- /*
- * Check along the bottom edge to make sure that there aren't any gaps between virtual
- * desktops.
- */
- for (y = desktopSpread.y, x = 0; x <= desktopSpread.x; x++) {
- if (unityDesktopLayout[x][y] < 0) {
- break;
- }
- }
- for (; x <= desktopSpread.x; x++) {
- if (unityDesktopLayout[x][y] >= 0) {
- Warning("Unity virtual desktop layout has holes along the bottom edge.\n");
- return FALSE;
- }
- }
-
- /*
- * Now we know we have a workable virtual desktop layout - let's figure out how to
- * communicate it to the window manager & pager.
- */
- up->desktopInfo.layoutData[0] = _NET_WM_ORIENTATION_HORZ; // Orientation
- up->desktopInfo.layoutData[1] = (desktopSpread.x + 1); // # of columns
- up->desktopInfo.layoutData[2] = (desktopSpread.y + 1); // # of rows
- up->desktopInfo.layoutData[3] = _NET_WM_TOPLEFT; // Starting corner
-
- if (((desktopSpread.x + 1) * (desktopSpread.y + 1)) >= (int)desktopConfig->desktopCount
- && desktopSpread.x > 0
- && desktopSpread.y > 1
- && unityDesktopLayout[desktopSpread.x][desktopSpread.y - 1] < 0) {
- /*
- * We know there is are least two holes at the end of the layout, /and/ the holes
- * go up the right side, so therefore we need to use vertical orientation for the
- * EWMH layout.
- */
- up->desktopInfo.layoutData[0] = _NET_WM_ORIENTATION_VERT;
- }
-
- /*
- * Figure out what the guest-side desktop IDs will be, based on our chosen
- * orientation.
- */
- i = 0;
- memset(guestDesktopLayout, 0xFF, sizeof guestDesktopLayout); // Set all entries to -1
- if (up->desktopInfo.layoutData[0] == _NET_WM_ORIENTATION_HORZ) {
- for (y = 0; y <= desktopSpread.y; y++) {
- for (x = 0; x <= desktopSpread.x; x++) {
- if (unityDesktopLayout[x][y] >= 0) {
- guestDesktopLayout[x][y] = i++;
- }
- }
- }
- } else {
- for (x = 0; x <= desktopSpread.x; x++) {
- for (y = 0; y <= desktopSpread.y; y++) {
- if (unityDesktopLayout[x][y] >= 0) {
- guestDesktopLayout[x][y] = i++;
- }
- }
- }
- }
-
- up->desktopInfo.numDesktops = desktopConfig->desktopCount;
-
- /*
- * Build tables to translate between guest-side and Unity-side desktop IDs.
- */
- up->desktopInfo.guestDesktopToUnity = (UnityDesktopId*)
- Util_SafeRealloc(up->desktopInfo.guestDesktopToUnity,
- up->desktopInfo.numDesktops
- * sizeof up->desktopInfo.guestDesktopToUnity[0]);
- up->desktopInfo.unityDesktopToGuest = (uint32*)
- Util_SafeRealloc(up->desktopInfo.unityDesktopToGuest,
- up->desktopInfo.numDesktops
- * sizeof up->desktopInfo.unityDesktopToGuest[0]);
- for (i = 0; i < up->desktopInfo.numDesktops; i++) {
- int guestNum;
- UnityVirtualDesktop curDesk = desktopConfig->desktops[i];
-
- guestNum = guestDesktopLayout[curDesk.x - minDesktop.x][curDesk.y - minDesktop.y];
- up->desktopInfo.guestDesktopToUnity[guestNum] = i;
- up->desktopInfo.unityDesktopToGuest[i] = guestNum;
- }
-
- /*
- * Make the configuration actually take effect.
- */
- UnityPlatformSyncDesktopConfig(up);
-
- return TRUE;
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityPlatformSetInitialDesktop --
- *
- * Set a desktop specified by the desktop id as the initial state.
- *
- * Results:
- * Returns TRUE if successful, and FALSE otherwise.
- *
- * Side effects:
- * Some windows might be hidden and some shown.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformSetInitialDesktop(UnityPlatform *up, // IN
- UnityDesktopId desktopId) // IN
-{
- ASSERT(up);
- up->desktopInfo.initialDesktop = desktopId;
- return UnityPlatformSetDesktopActive(up, desktopId);
-}
-
-
-/*
- *------------------------------------------------------------------------------
- *
- * UnityPlatformSetDesktopActive --
- *
- * Switch to the specified virtual desktop. The desktopId is an index
- * into the desktop configuration array.
- *
- * Results:
- * Returns TRUE if successful, and FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformSetDesktopActive(UnityPlatform *up, // IN
- UnityDesktopId desktopId) // IN
-{
- ASSERT(up);
-
- /*
- * Update the uwt with the new active desktop info.
- */
-
- UnityWindowTracker_ChangeActiveDesktop(up->tracker, desktopId);
-
- if (desktopId >= (UnityDesktopId)up->desktopInfo.numDesktops) {
- return FALSE;
- }
-
- if (!up->rootWindows) {
- /*
- * We may not be into Unity mode yet, but we pretend it succeeded, and then do the
- * switch later for real.
- */
- return TRUE;
- }
-
- UnityX11SetCurrentDesktop(up, up->desktopInfo.unityDesktopToGuest[desktopId]);
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformDoUpdate --
- *
- * This function is used to (possibly asynchronously) collect Unity window
- * updates and send them to the host via the RPCI update channel.
- *
- * Results:
- * Updates will be collected. Updates may be sent.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformDoUpdate(UnityPlatform *up, // IN:
- Bool incremental) // IN: Incremental vs. full update
-{
- int flags = 0;
-
- ASSERT(up);
-
- if (incremental) {
- flags |= UNITY_UPDATE_INCREMENTAL;
- } else {
- /*
- * Only update the window state for full updates. Incremental updates can be
- * satisfied by the current state in the tracker.
- */
- UnityPlatformUpdateWindowState(up, up->tracker);
- }
-
- up->hostCallbacks.buildUpdateCB(up->hostCallbacks.updateCbCtx, flags);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_UnityToLocalPoint --
- *
- * Initializes localPt structure based on the input unityPt structure.
- * Translate point from Unity coordinate to local coordinate.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *----------------------------------------------------------------------------
- */
-
-void
-Unity_UnityToLocalPoint(UnityPoint *localPt, // IN/OUT
- UnityPoint *unityPt) // IN
-{
- ASSERT(localPt);
- ASSERT(unityPt);
- localPt->x = unityPt->x;
- localPt->y = unityPt->y;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Unity_LocalToUnityPoint --
- *
- * Initializes unityPt structure based on the input localPt structure.
- * Translate point from local coordinate to Unity coordinate.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *----------------------------------------------------------------------------
- */
-
-void
-Unity_LocalToUnityPoint(UnityPoint *unityPt, // IN/OUT
- UnityPoint *localPt) // IN
-{
- ASSERT(unityPt);
- ASSERT(localPt);
- unityPt->x = localPt->x;
- unityPt->y = localPt->y;
-}
-
-
-/*
- ******************************************************************************
- * UnityPlatformStickWindow -- */ /**
- *
- * @brief "Stick" a window to the desktop.
- *
- * @param[in] up Platform context.
- * @param[in] windowId Operand window.
- *
- * @retval TRUE Success.
- * @retval FALSE Failure.
- *
- ******************************************************************************
- */
-
-Bool
-UnityPlatformStickWindow(UnityPlatform *up, // IN
- UnityWindowId windowId) // IN
-{
- return SetWindowStickiness(up, windowId, TRUE);
-}
-
-
-/*
- ******************************************************************************
- * UnityPlatformUnstickWindow -- */ /**
- *
- * @brief "Unstick" a window from the desktop.
- *
- * @param[in] up Platform context.
- * @param[in] windowId Operand window.
- *
- * @retval TRUE Success.
- * @retval FALSE Failure.
- *
- ******************************************************************************
- */
-
-Bool
-UnityPlatformUnstickWindow(UnityPlatform *up, // IN
- UnityWindowId windowId) // IN
-{
- return SetWindowStickiness(up, windowId, FALSE);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformSetConfigDesktopColor --
- *
- * Set the preferred desktop background color for use when in Unity Mode.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-UnityPlatformSetConfigDesktopColor(UnityPlatform *up, int desktopColor)
-{
- ASSERT(up);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformRequestWindowContents --
- *
- * Validate the list of supplied window IDs and once validated add them to a list
- * of windows whose contents should be sent to the host.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformRequestWindowContents(UnityPlatform *up,
- UnityWindowId windowIds[],
- uint32 numWindowIds)
-{
- ASSERT(up);
-
- /* Not implemented */
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformConfirmMinimizeOperation --
- *
- * Minimize a window (if allowed) by the host.
- *
- * Results:
- * Returns TRUE if successful, and FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformConfirmMinimizeOperation(UnityPlatform *up, // IN
- UnityWindowId windowId, // IN
- uint32 sequence, // IN
- Bool allow) // IN
-{
- ASSERT(up);
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformSetInterlockMinimizeOperation --
- *
- * Enable (or Disable) the interlocking (relaying) of minimize operations
- * through the host.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-void UnityPlatformSetInterlockMinimizeOperation(UnityPlatform *up, // IN
- Bool enabled) // IN
-{
- ASSERT(up);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformSetDisableCompositing --
- *
- * Disable (or Enable) the compositing features of the window manager the
- * next time Unity starts.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-void UnityPlatformSetDisableCompositing(UnityPlatform *up, // IN
- Bool disabled) // IN
-{
- ASSERT(up);
-}
-
-
-/*
- ******************************************************************************
- * Begin file-scope functions.
- *
- */
-
-
-/*
- ******************************************************************************
- * GetRelevantWMWindow -- */ /**
- *
- * @brief Given a UnityWindowId, return the X11 window relevant to WM operations.
- *
- * Starting with a Unity window, look for and return its associated
- * clientWindow. If there is no clientWindow, then return the top-level window.
- *
- * @param[in] up Unity/X11 context.
- * @param[in] windowId Window search for.
- * @param[out] wmWindow Set to the relevant X11 window.
- *
- * @todo Consider exporting this for use in unityPlatformX11Window.c.
- *
- * @retval TRUE Relevant window found and recorded in @a wmWindow.
- * @retval FALSE Unable to find @a windowId.
- *
- ******************************************************************************
- */
-
-static Bool
-GetRelevantWMWindow(UnityPlatform *up, // IN
- UnityWindowId windowId, // IN
- Window *wmWindow) // OUT
-{
- UnityPlatformWindow *upw;
-
- ASSERT(up);
-
- upw = UPWindow_Lookup(up, windowId);
- if (!upw) {
- return FALSE;
- }
-
- *wmWindow = upw->clientWindow ? upw->clientWindow : upw->toplevelWindow;
- return TRUE;
-}
-
-
-/*
- ******************************************************************************
- * SetWindowStickiness -- */ /**
- *
- * @brief Sets or clears a window's sticky state.
- *
- * @param[in] up Unity/X11 context.
- * @param[in] windowId Operand window.
- * @param[in] wantSticky Set to TRUE to stick a window, FALSE to unstick it.
- *
- * @retval TRUE Request successfully sent to X server.
- * @retval FALSE Request failed.
- *
- ******************************************************************************
- */
-
-static Bool
-SetWindowStickiness(UnityPlatform *up, // IN
- UnityWindowId windowId, // IN
- Bool wantSticky) // IN
-{
- GdkWindow *gdkWindow;
- Window curWindow;
-
- ASSERT(up);
-
- if (!GetRelevantWMWindow(up, windowId, &curWindow)) {
- Debug("%s: Lookup against window %#x failed.\n", __func__, windowId);
- return FALSE;
- }
-
- gdkWindow = gdk_window_foreign_new(curWindow);
- if (gdkWindow == NULL) {
- Debug("%s: Unable to create Gdk window?! (%#x)\n", __func__, windowId);
- return FALSE;
- }
-
- if (wantSticky) {
- gdk_window_stick(gdkWindow);
- } else {
- gdk_window_unstick(gdkWindow);
- }
-
- gdk_flush();
- g_object_unref(G_OBJECT(gdkWindow));
-
- return TRUE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * UnityPlatformSendMouseWheel --
- *
- * Sends the given mouse wheel event to the window at the given location.
- *
- * Results:
- * Returns TRUE if successful, and FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *------------------------------------------------------------------------------
- */
-
-Bool
-UnityPlatformSendMouseWheel(UnityPlatform *up, // IN
- int32 deltaX, // IN
- int32 deltaY, // IN
- int32 deltaZ, // IN
- uint32 modifierFlags) // IN
-{
- ASSERT(up);
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * MakeCompositeOverlaysObject --
- *
- * Probes X server for any composite overlay windows. If found, they're
- * monitored as UnitySpecialWindows whereby we won't mistakenly place them
- * in the global window tracker.
- *
- * Results:
- * Returns pointer to new UnitySpecialWindow on success, NULL on failure.
- *
- * Side effects:
- * If overlay windows haven't yet been mapped, they will be (temporarily).
- *
- * Caller doesn't need to free returned UnitySpecialWindow*. That's handled
- * automatically when exiting Unity.
- *
- *-----------------------------------------------------------------------------
- */
-
-static UnitySpecialWindow *
-MakeCompositeOverlaysObject(UnityPlatform *up) // IN
-{
- ASSERT(up);
- ASSERT(up->rootWindows);
-
-#ifndef NO_XCOMPOSITE
- int eventBase;
- int errorBase;
- if (XCompositeQueryExtension(up->display, &eventBase, &errorBase)) {
- /*
- * XCompositeGetOverlayWindow didn't appear until XComposite 0.3.
- */
- int major = 0;
- int minor = 0;
- XCompositeQueryVersion(up->display, &major, &minor);
- if (major > 0 || (major == 0 && minor >= 3)) {
- size_t nWindows = up->rootWindows->numWindows;
- Window *overlays = (Window*)Util_SafeCalloc(nWindows, sizeof *overlays);
- for (unsigned int i = 0; i < nWindows; i++) {
- overlays[i] = XCompositeGetOverlayWindow(up->display,
- up->rootWindows->windows[i]);
- XCompositeReleaseOverlayWindow(up->display, overlays[i]);
- }
-
- /*
- * Note 1: See above. Caller doesn't need to need to track this explicitly.
- * Note 2: The NULL event handler parameter is how we tell the X event handling
- * pieces to ignore this window, thereby keeping it out of the window
- * tracker.
- */
- return USWindowCreate(up, NULL, overlays, nWindows);
- }
- }
-#endif // ifndef NO_XCOMPOSITE
-
- return NULL;
-}
-
-/*
- *
- * End file-scope functions.
- ******************************************************************************
- */
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2007-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.
- *
- *********************************************************/
-
-/*
- * x11Platform.h --
- *
- * Internal state shared between the various modules that implement Unity for X11.
- */
-
-#ifndef _X11PLATFORM_H_
-#define _X11PLATFORM_H_
-
-/*
- * It's necessary to include glib, gtk+, and Xlib before the rest of the header files,
- * and then #undef bool. This is because Xlib has '#define Bool int', while
- * vm_basic_types.h has 'typedef char Bool;'.
- */
-
-#include "vmware/tools/unity/windowPathFactory.hh"
-
-extern "C" {
-#include <glib.h>
-#include <gdk/gdkx.h>
-#include <gtk/gtk.h>
-#include <X11/Xlib.h>
-#include <X11/Xmd.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/scrnsaver.h>
-#if defined(ScreenSaverMajorVersion) && defined(ScreenSaverMinorVersion)
-#define VM_HAVE_X11_SS_EXT 1
-#endif
-#include <X11/extensions/shape.h>
-#if defined(ShapeNumberEvents)
-#define VM_HAVE_X11_SHAPE_EXT 1
-#endif
-#undef Bool
-
-#include "vmware.h"
-#include "vmware/tools/guestrpc.h"
-#include "rpcin.h"
-#include "rpcout.h"
-#include "unity.h"
-#include "unityCommon.h"
-#include "unityPlatform.h"
-#include "debug.h"
-#include "str.h"
-#include "strutil.h"
-#include "util.h"
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-}
-
-
-/*
- * Warn builders up front that GTK 2 is mandatory.
- */
-#ifndef GTK2
-# error UnityX11 depends on GTK+ 2.
-#endif
-
-
-/*
- * These defines are listed in the EWMH spec, but not available in any header file that I
- * know of.
- */
-#ifndef _NET_WM_ORIENTATION_HORZ
-#define _NET_WM_ORIENTATION_HORZ 0
-#define _NET_WM_ORIENTATION_VERT 1
-
-#define _NET_WM_TOPLEFT 0
-#define _NET_WM_TOPRIGHT 1
-#define _NET_WM_BOTTOMRIGHT 2
-#define _NET_WM_BOTTOMLEFT 3
-
-#define _NET_WM_STATE_REMOVE 0
-#define _NET_WM_STATE_ADD 1
-#endif
-
-/*
- * These describe system settings saved when entering Unity mode, and restored upon
- * exiting.
- */
-typedef enum {
- UNITY_UI_SCREENSAVER,
- UNITY_UI_TASKBAR_VISIBLE,
-#ifdef VM_UNIMPLEMENTED_UNITY_SETTINGS
- UNITY_UI_DROP_SHADOW,
- UNITY_UI_MENU_ANIMATION,
- UNITY_UI_TOOLTIP_ANIMATION,
- UNITY_UI_WINDOW_ANIMATION,
- UNITY_UI_FULL_WINDOW_DRAG,
-#endif
-
- UNITY_UI_MAX_SETTINGS
-} UnityUISetting;
-
-typedef enum {
- UNITY_X11_WM__NET_MOVERESIZE_WINDOW,
- UNITY_X11_WM__NET_CLOSE_WINDOW,
- UNITY_X11_WM__NET_RESTACK_WINDOW,
- UNITY_X11_WM__NET_ACTIVE_WINDOW,
- UNITY_X11_WM__NET_WM_ACTION_MINIMIZE,
- UNITY_X11_WM__NET_WM_ACTION_CLOSE,
- UNITY_X11_WM__NET_WM_ACTION_SHADE,
- UNITY_X11_WM__NET_WM_ACTION_STICK,
- UNITY_X11_WM__NET_WM_ACTION_FULLSCREEN,
- UNITY_X11_WM__NET_WM_ACTION_MAXIMIZE_HORZ,
- UNITY_X11_WM__NET_WM_ACTION_MAXIMIZE_VERT,
- UNITY_X11_WM__NET_FRAME_EXTENTS,
- UNITY_X11_WM__NET_WM_STRUT_PARTIAL,
- UNITY_X11_WM__NET_WM_STATE_HIDDEN,
- UNITY_X11_WM__NET_WM_STATE_MINIMIZED,
-
- UNITY_X11_MAX_WM_PROTOCOLS
-} UnityX11WMProtocol;
-
-typedef enum {
- UNITY_X11_WIN_WM_DELETE_WINDOW,
- UNITY_X11_MAX_WIN_PROTOCOLS
-} UnityX11WinProtocol;
-
-
-/*
- * UnitySpecialWindow objects track windows that need special treatment, including root
- * windows and windows that we create.
- */
-typedef struct UnitySpecialWindow UnitySpecialWindow;
-typedef void (*UnitySpecialEventHandler)(UnityPlatform *up,
- UnitySpecialWindow *usw,
- const XEvent *xevent,
- Window realEventWindow);
-
-struct UnitySpecialWindow {
- UnitySpecialEventHandler evHandler;
- Window *windows;
- size_t numWindows;
- Bool windowsAreOwned;
-};
-
-typedef struct UnityPlatformWindow UnityPlatformWindow;
-
-
-/**
- * Custom Glib source to monitor the Xlib queue and X11 socket(s).
- *
- * This structure is "derived from" GSource. It will be recast and used as
- * a GSource with Glib functions.
- */
-
-typedef struct {
- GSource base; ///< Owned by Glib. Hands off!
- UnityPlatform *up; ///< Our running UnityPlatform context.
- GHashTable *fdTable; ///< file descriptor => GPollFD *.
-} UnityGSource;
-
-
-/**
- * Holds platform-specific data.
- */
-struct _UnityPlatform {
- Display *display; // X11 display object
- long eventTimeDiff; // Diff between X server time and our local time
- /**
- * Integrates Unity event sources with the Glib main loop.
- *
- * Monitors dedicated Unity X11 socket(s) and the associated Xlib event
- * queue. Its lifetime is for the duration that the user is in Unity mode.
- *
- * @note
- * The event source is created in UnityPlatformStartHelperThreads and torn
- * down in UnityPlatformKillHelperThreads.
- */
- UnityGSource *glibSource;
-
- struct { // Atoms that we'll find useful
- Atom _NET_WM_WINDOW_TYPE,
- _NET_WM_WINDOW_TYPE_DESKTOP,
- _NET_WM_WINDOW_TYPE_DOCK,
- _NET_WM_WINDOW_TYPE_TOOLBAR,
- _NET_WM_WINDOW_TYPE_TOOLTIP,
- _NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
- _NET_WM_WINDOW_TYPE_POPUP_MENU,
- _NET_WM_WINDOW_TYPE_MENU,
- _NET_WM_WINDOW_TYPE_UTILITY,
- _NET_WM_WINDOW_TYPE_SPLASH,
- _NET_WM_WINDOW_TYPE_DIALOG,
- _NET_WM_WINDOW_TYPE_NORMAL,
- _NET_WM_WINDOW_TYPE_DND,
- _NET_WM_ALLOWED_ACTIONS,
- _NET_WM_ACTION_MOVE,
- _NET_WM_ACTION_RESIZE,
- _NET_WM_ACTION_MINIMIZE,
- _NET_WM_ACTION_SHADE,
- _NET_WM_ACTION_STICK,
- _NET_WM_ACTION_MAXIMIZE_HORZ,
- _NET_WM_ACTION_MAXIMIZE_VERT,
- _NET_WM_ACTION_FULLSCREEN,
- _NET_WM_ACTION_CHANGE_DESKTOP,
- _NET_WM_ACTION_CLOSE,
- _NET_WM_STATE,
- _NET_WM_STATE_HIDDEN,
- _NET_WM_STATE_MODAL,
- _NET_WM_STATE_STICKY,
- _NET_WM_STATE_MINIMIZED,
- _NET_WM_STATE_MAXIMIZED_HORZ,
- _NET_WM_STATE_MAXIMIZED_VERT,
- _NET_WM_STATE_SHADED,
- _NET_WM_STATE_SKIP_TASKBAR,
- _NET_WM_STATE_SKIP_PAGER,
- _NET_WM_STATE_FULLSCREEN,
- _NET_WM_STATE_ABOVE,
- _NET_WM_STATE_BELOW,
- _NET_WM_STATE_DEMANDS_ATTENTION,
- _NET_WM_USER_TIME,
- _NET_WM_USER_TIME_WINDOW,
- _NET_ACTIVE_WINDOW,
- _NET_RESTACK_WINDOW,
- _NET_WM_PID,
- _NET_WM_ICON,
- _NET_MOVERESIZE_WINDOW,
- _NET_CLOSE_WINDOW,
- _NET_WM_STRUT,
- _NET_WM_STRUT_PARTIAL,
- _NET_NUMBER_OF_DESKTOPS,
- _NET_WM_DESKTOP,
- _NET_CURRENT_DESKTOP,
- _NET_DESKTOP_LAYOUT,
- _NET_SUPPORTED,
- _NET_FRAME_EXTENTS,
- WM_CLASS,
- WM_CLIENT_LEADER,
- WM_DELETE_WINDOW,
- WM_ICON,
- WM_NAME,
- WM_PROTOCOLS,
- WM_STATE,
- WM_TRANSIENT_FOR,
- WM_WINDOW_ROLE,
- COMPOUND_TEXT,
- UTF8_STRING;
- } atoms;
-
- UnityWindowTracker *tracker;
- UnityHostCallbacks hostCallbacks;
-
- /*
- * This tracks all toplevel windows, whether or not they are showing through to the
- * window tracker. It also has entries for client windows (which point to the same
- * UnityPlatformWindow objects).
- */
- HashTable *allWindows;
- UnityPlatformWindow *topWindow; // For tracking Z-ordering
-
- /*
- * This tracks "special" windows, including root windows, the DnD detection window,
- * and the work area-faking window(s). It's mainly used to make sure these windows
- * get proper event handling.
- */
- HashTable *specialWindows;
- UnitySpecialWindow *rootWindows;
-
- UnityPlatformWindow *desktopWindow;
- UnityDnD dnd;
-
- UnitySpecialWindow *workAreas;
-
- UnityRect *needWorkAreas;
- int needNumWorkAreas;
-
- struct {
- /*
- * Hopefully, most of the time the desktopIDs on host and guest
- * will be the same, but we can't count on it, so these two arrays
- * translate back and forth between guest and unity desktop IDs.
- */
- UnityDesktopId *guestDesktopToUnity;
- uint32 *unityDesktopToGuest;
- size_t numDesktops;
-
- Atom layoutData[4];
-
- Atom savedLayoutData[4];
- size_t savedNumDesktops;
- uint32 savedCurrentDesktop;
- uint32 currentDesktop;
- /*
- * Set by the set.desktop.active RPC to indicate which desktop the host is in
- * when we enter Unity.
- */
- uint32 initialDesktop;
-#define UNITY_X11_INITIALDESKTOP_UNSET MAX_UINT32
- } desktopInfo;
-
- Bool isRunning;
- Bool stackingChanged;
-
- Bool haveOriginalSettings;
- Bool currentSettings[UNITY_UI_MAX_SETTINGS];
- Bool originalSettings[UNITY_UI_MAX_SETTINGS];
- Bool needTaskbarSetting;
-
- int savedScreenSaverTimeout;
-
- Bool wmProtocols[UNITY_X11_MAX_WM_PROTOCOLS];
-
- int shapeEventBase;
- int shapeErrorBase;
-
- vmware::tools::unity::WindowPathFactory* wpFactory;
-};
-
-/*
- * Holds per-window platform-specific data.
- */
-
-struct UnityPlatformWindow {
- int refs;
-
- /*
- * In X11, we want to watch both the top-level window (normally created by the window
- * manager) and the application's window. The UnityWindowId will correspond to the
- * former - to save lookups later, we track both of them here, as well as their root
- * window.
- */
- Window toplevelWindow;
- Window clientWindow;
- Window rootWindow;
- int screenNumber;
- int desktopNumber;
- int onUnmapDesktopNumber; ///< @sa wantSetDesktopNumberOnUnmap
- UnityPlatformWindow *higherWindow;
- UnityPlatformWindow *lowerWindow;
-
- UnityWindowType windowType;
-
- struct {
- DynBuf data;
- UnityIconSize size;
- UnityIconType type;
- } iconPng;
-
- Bool windowProtocols[UNITY_X11_MAX_WIN_PROTOCOLS];
-
- Bool isRelevant; // Whether the window is relayed through the window tracker
- Bool isOverrideRedirect; // Allow detecting changes in this attr
- Bool isViewable;
- Bool wasViewable;
- Bool wantInputFocus;
- /**
- * Indicates we wish to force a value of _NET_CURRENT_DESKTOP across XUnmapWindow.
- *
- * When we unmap a window, its _NET_CURRENT_DESKTOP property is cleared. There are
- * some circumstances in which this behavior is undesirable. (E.g., once we hide
- * the KDE taskbar, it will only appear on desktop #0 after exiting Unity, as KDE
- * doesn't automatically remap panel/dock windows as sticky windows.)
- *
- * Setting this flag (in combination with setting onUnmapDesktopNumber) causes
- * us to reset the _NET_CURRENT_DESKTOP property in response to receiving its
- * PropertyDelete. If a PropertyNewValue arrives before the -Delete, we'll query
- * and record the new value into onUnmapDesktopNumber (if the property exists).
- */
- Bool wantSetDesktopNumberOnUnmap;
-
- /*
- * Mini state-machine:
- *
- * isMaximized, isMinimized, and isHidden can all be set or unset independently
- * from the host's perspective.
- *
- * isMaximized can pretty much be set independently.
- * Leaving isHidden requires WM_HINTS to be set correctly.
- * Entering isHidden requires XWithdrawWindow.
- * If !isHidden, !isMinimized -> isMinimized requires XIconifyWindow()
- * If !isHidden, isMinimized -> !isMinimized requires just mapping the window.
- */
- Bool isHidden;
- Bool isMinimized;
- Bool isMaximized;
-
- /*
- * When a client window is reparented by a window manager, a ReparentNotify event
- * is generated. We're interested in this event, because it tells us that the
- * relationship between this UnityPlatformWindow and its top-level and client
- * windows has changed.
- *
- * Per ICCCM ยง4.1.3.1, we identify the client window as the window within a
- * tree possessing the WM_STATE property. Unfortunately, this property may
- * not yet be set when we receive ReparentNotify. If that's the case, this flag
- * is raised such that once we do see a WM_STATE change related to one of
- * our windows (via a PropertyNotify event), we may act accordingly.
- */
- Bool waitingForWmState;
-
- /*
- * It isn't safe to delete a UnityPlatformWindow object in the guts of the
- * event processing code. (Example: processing a DestroyNotify event or
- * learning that a window is irrelevant to Unity/X11.) Unfortunately, other
- * parts of this codebase don't use the ref counting scheme correctly, so
- * this hack will simply mark a UPW for deletion, and the outermost event
- * entry point will take care of deleting if set.
- *
- * XXX Ditch this flag and instead make use of the reference counting
- * bits.
- */
- Bool deleteWhenSafe;
-
- /*
- * See wm-spec::_NET_FRAME_EXTENTS.
- */
- uint32 frameExtents[4];
-};
-
-/*
- * Implemented by unityPlatformX11Window.c
- */
-void UPWindow_ProcessEvent(UnityPlatform *up,
- UnityPlatformWindow *upw,
- Window realEventWindow,
- const XEvent *xevent);
-UnityPlatformWindow *UPWindow_Create(UnityPlatform *up, Window window);
-void UPWindow_CheckRelevance(UnityPlatform *up,
- UnityPlatformWindow *upw,
- const XEvent *motivator);
-void UPWindow_Ref(UnityPlatform *up, UnityPlatformWindow *upw);
-void UPWindow_Restack(UnityPlatform *up, UnityPlatformWindow *upw, Window above);
-void UPWindow_Unref(UnityPlatform *up, UnityPlatformWindow *upw);
-Bool UPWindow_ProtocolSupported(const UnityPlatform *up,
- const UnityPlatformWindow *upw,
- UnityX11WinProtocol proto);
-UnityPlatformWindow *UPWindow_Lookup(UnityPlatform *up, Window window);
-void UPWindow_SetUserTime(UnityPlatform *up,
- UnityPlatformWindow *upw);
-void UPWindow_SetEWMHDesktop(UnityPlatform *up,
- UnityPlatformWindow *upw,
- uint32 ewmhDesktopId);
-
-/*
- * Implemented by unityPlatformX11.c
- */
-Bool UnityPlatformWMProtocolSupported(UnityPlatform *up, UnityX11WMProtocol proto);
-Bool UnityPlatformIsRootWindow(UnityPlatform *up, Window window);
-uint32 UnityX11GetCurrentDesktop(UnityPlatform *up);
-void UnityX11SetCurrentDesktop(UnityPlatform *up, uint32 currentDesktop);
-Time UnityPlatformGetServerTime(UnityPlatform *up);
-
-#define UnityPlatformProcessMainLoop() g_main_context_iteration(NULL, TRUE)
-
-int UnityPlatformGetErrorCount(UnityPlatform *up);
-void UnityPlatformResetErrorCount(UnityPlatform *up);
-Bool UnityPlatformSetTaskbarVisible(UnityPlatform *up, Bool currentSetting);
-void UnityPlatformSendClientMessage(UnityPlatform *up, Window destWindow,
- Window w, Atom messageType,
- int format, int numItems, const void *data);
-void UnityPlatformSyncDesktopConfig(UnityPlatform *up);
-void UnityX11SaveSystemSettings(UnityPlatform *up);
-void UnityX11RestoreSystemSettings(UnityPlatform *up);
-size_t UnityPlatformGetNumVirtualDesktops(UnityPlatform *up);
-void UnityPlatformGetVirtualDesktopLayout(UnityPlatform *up, Atom *layoutData);
-const char *UnityPlatformGetEventString(UnityPlatform *up, int type);
-
-gboolean UnityX11HandleEvents(gpointer data);
-
-
-/*
- * Implemented in x11Event.c.
- */
-
-void UnityX11EventEstablishSource(UnityPlatform *up);
-void UnityX11EventTeardownSource(UnityPlatform *up);
-
-
-/*
- * Implemented in x11Util.c.
- */
-
-Bool UnityX11Util_IsWindowDecorationWidget(UnityPlatform *up,
- Window operand);
-
-#endif // _X11PLATFORM_H_