Blame gtk/gtksocket-win32.c

Packit 98cdb6
/* GTK - The GIMP Toolkit
Packit 98cdb6
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
Packit 98cdb6
 * Copyright (C) 2005 Novell, Inc.
Packit 98cdb6
 *
Packit 98cdb6
 * This library is free software; you can redistribute it and/or
Packit 98cdb6
 * modify it under the terms of the GNU Lesser General Public
Packit 98cdb6
 * License as published by the Free Software Foundation; either
Packit 98cdb6
 * version 2 of the License, or (at your option) any later version.
Packit 98cdb6
 *
Packit 98cdb6
 * This library is distributed in the hope that it will be useful,
Packit 98cdb6
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 98cdb6
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 98cdb6
 * Lesser General Public License for more details.
Packit 98cdb6
 *
Packit 98cdb6
 * You should have received a copy of the GNU Lesser General Public
Packit 98cdb6
 * License along with this library; if not, write to the Free
Packit 98cdb6
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
/* By Tor Lillqvist <tml@novell.com> 2005 */
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * Modified by the GTK+ Team and others 1997-2005.  See the AUTHORS
Packit 98cdb6
 * file for a list of people on the GTK+ Team.  See the ChangeLog
Packit 98cdb6
 * files for a list of changes.  These files are distributed with
Packit 98cdb6
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#include "config.h"
Packit 98cdb6
#include <string.h>
Packit 98cdb6
Packit 98cdb6
#include "gtkwindow.h"
Packit 98cdb6
#include "gtkplug.h"
Packit 98cdb6
#include "gtkprivate.h"
Packit 98cdb6
#include "gtksocket.h"
Packit 98cdb6
#include "gtksocketprivate.h"
Packit 98cdb6
Packit 98cdb6
#include "win32/gdkwin32.h"
Packit 98cdb6
Packit 98cdb6
#include "gtkwin32embed.h"
Packit 98cdb6
#include "gtkalias.h"
Packit 98cdb6
Packit 98cdb6
GdkNativeWindow
Packit 98cdb6
_gtk_socket_windowing_get_id (GtkSocket *socket)
Packit 98cdb6
{
Packit 98cdb6
  g_return_val_if_fail (GTK_IS_SOCKET (socket), 0);
Packit 98cdb6
  g_return_val_if_fail (GTK_WIDGET_ANCHORED (socket), 0);
Packit 98cdb6
Packit 98cdb6
  if (!gtk_widget_get_realized (socket))
Packit 98cdb6
    gtk_widget_realize (GTK_WIDGET (socket));
Packit 98cdb6
Packit 98cdb6
  return (GdkNativeWindow) GDK_WINDOW_HWND (GTK_WIDGET (socket)->window);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_socket_windowing_realize_window (GtkSocket *socket)
Packit 98cdb6
{
Packit 98cdb6
  /* XXX Anything needed? */
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_socket_windowing_end_embedding_toplevel (GtkSocket *socket)
Packit 98cdb6
{
Packit 98cdb6
  gtk_window_remove_embedded_xid (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (socket))),
Packit 98cdb6
				  GDK_WINDOW_HWND (socket->plug_window));
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_socket_windowing_size_request (GtkSocket *socket)
Packit 98cdb6
{
Packit 98cdb6
  MINMAXINFO mmi;
Packit 98cdb6
Packit 98cdb6
  socket->request_width = 1;
Packit 98cdb6
  socket->request_height = 1;
Packit 98cdb6
  
Packit 98cdb6
  mmi.ptMaxSize.x = mmi.ptMaxSize.y = 16000; /* ??? */
Packit 98cdb6
  mmi.ptMinTrackSize.x = mmi.ptMinTrackSize.y = 1;
Packit 98cdb6
  mmi.ptMaxTrackSize.x = mmi.ptMaxTrackSize.y = 16000; /* ??? */
Packit 98cdb6
  mmi.ptMaxPosition.x = mmi.ptMaxPosition.y = 0;
Packit 98cdb6
Packit 98cdb6
  if (SendMessage (GDK_WINDOW_HWND (socket->plug_window), WM_GETMINMAXINFO,
Packit 98cdb6
		   0, (LPARAM) &mmi) == 0)
Packit 98cdb6
    {
Packit 98cdb6
      socket->request_width = mmi.ptMinTrackSize.x;
Packit 98cdb6
      socket->request_height = mmi.ptMinTrackSize.y;
Packit 98cdb6
    }
Packit 98cdb6
  socket->have_size = TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_socket_windowing_send_key_event (GtkSocket *socket,
Packit 98cdb6
				      GdkEvent  *gdk_event,
Packit 98cdb6
				      gboolean   mask_key_presses)
Packit 98cdb6
{
Packit 98cdb6
  PostMessage (GDK_WINDOW_HWND (socket->plug_window),
Packit 98cdb6
	       (gdk_event->type == GDK_KEY_PRESS ? WM_KEYDOWN : WM_KEYUP),
Packit 98cdb6
	       gdk_event->key.hardware_keycode, 0);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_socket_windowing_focus_change (GtkSocket *socket,
Packit 98cdb6
				    gboolean   focus_in)
Packit 98cdb6
{
Packit 98cdb6
  if (focus_in)
Packit 98cdb6
    _gtk_win32_embed_send_focus_message (socket->plug_window,
Packit 98cdb6
					 GTK_WIN32_EMBED_FOCUS_IN,
Packit 98cdb6
					 GTK_WIN32_EMBED_FOCUS_CURRENT);
Packit 98cdb6
  else
Packit 98cdb6
    _gtk_win32_embed_send (socket->plug_window,
Packit 98cdb6
			   GTK_WIN32_EMBED_FOCUS_OUT,
Packit 98cdb6
			   0, 0);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_socket_windowing_update_active (GtkSocket *socket,
Packit 98cdb6
				     gboolean   active)
Packit 98cdb6
{
Packit 98cdb6
  _gtk_win32_embed_send (socket->plug_window,
Packit 98cdb6
			 (active ? GTK_WIN32_EMBED_WINDOW_ACTIVATE : GTK_WIN32_EMBED_WINDOW_DEACTIVATE),
Packit 98cdb6
			 0, 0);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_socket_windowing_update_modality (GtkSocket *socket,
Packit 98cdb6
				       gboolean   modality)
Packit 98cdb6
{
Packit 98cdb6
  _gtk_win32_embed_send (socket->plug_window,
Packit 98cdb6
			 (modality ? GTK_WIN32_EMBED_MODALITY_ON : GTK_WIN32_EMBED_MODALITY_OFF),
Packit 98cdb6
			 0, 0);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_socket_windowing_focus (GtkSocket       *socket,
Packit 98cdb6
			     GtkDirectionType direction)
Packit 98cdb6
{
Packit 98cdb6
  int detail = -1;
Packit 98cdb6
Packit 98cdb6
  switch (direction)
Packit 98cdb6
    {
Packit 98cdb6
    case GTK_DIR_UP:
Packit 98cdb6
    case GTK_DIR_LEFT:
Packit 98cdb6
    case GTK_DIR_TAB_BACKWARD:
Packit 98cdb6
      detail = GTK_WIN32_EMBED_FOCUS_LAST;
Packit 98cdb6
      break;
Packit 98cdb6
    case GTK_DIR_DOWN:
Packit 98cdb6
    case GTK_DIR_RIGHT:
Packit 98cdb6
    case GTK_DIR_TAB_FORWARD:
Packit 98cdb6
      detail = GTK_WIN32_EMBED_FOCUS_FIRST;
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  _gtk_win32_embed_send_focus_message (socket->plug_window,
Packit 98cdb6
				       GTK_WIN32_EMBED_FOCUS_IN,
Packit 98cdb6
				       detail);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_socket_windowing_send_configure_event (GtkSocket *socket)
Packit 98cdb6
{
Packit 98cdb6
  /* XXX Nothing needed? */
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_socket_windowing_select_plug_window_input (GtkSocket *socket)
Packit 98cdb6
{
Packit 98cdb6
  /* XXX Nothing needed? */
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_socket_windowing_embed_get_info (GtkSocket *socket)
Packit 98cdb6
{
Packit 98cdb6
  socket->is_mapped = TRUE;	/* XXX ? */
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_socket_windowing_embed_notify (GtkSocket *socket)
Packit 98cdb6
{
Packit 98cdb6
  /* XXX Nothing needed? */
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
gboolean
Packit 98cdb6
_gtk_socket_windowing_embed_get_focus_wrapped (void)
Packit 98cdb6
{
Packit 98cdb6
  return _gtk_win32_embed_get_focus_wrapped ();
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_socket_windowing_embed_set_focus_wrapped (void)
Packit 98cdb6
{
Packit 98cdb6
  _gtk_win32_embed_set_focus_wrapped ();
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GdkFilterReturn
Packit 98cdb6
_gtk_socket_windowing_filter_func (GdkXEvent *gdk_xevent,
Packit 98cdb6
				   GdkEvent  *event,
Packit 98cdb6
				   gpointer   data)
Packit 98cdb6
{
Packit 98cdb6
  GtkSocket *socket;
Packit 98cdb6
  GtkWidget *widget;
Packit 98cdb6
  MSG *msg;
Packit 98cdb6
  GdkFilterReturn return_val;
Packit 98cdb6
Packit 98cdb6
  socket = GTK_SOCKET (data);
Packit 98cdb6
Packit 98cdb6
  return_val = GDK_FILTER_CONTINUE;
Packit 98cdb6
Packit 98cdb6
  if (socket->plug_widget)
Packit 98cdb6
    return return_val;
Packit 98cdb6
Packit 98cdb6
  widget = GTK_WIDGET (socket);
Packit 98cdb6
  msg = (MSG *) gdk_xevent;
Packit 98cdb6
Packit 98cdb6
  switch (msg->message)
Packit 98cdb6
    {
Packit 98cdb6
    default:
Packit 98cdb6
      if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_PARENT_NOTIFY))
Packit 98cdb6
	{
Packit 98cdb6
	  GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PARENT_NOTIFY received window=%p version=%d\n",
Packit 98cdb6
					    (gpointer) msg->wParam, (int) msg->lParam));
Packit 98cdb6
	  /* If we some day different protocols deployed need to add
Packit 98cdb6
	   * some more elaborate version handshake
Packit 98cdb6
	   */
Packit 98cdb6
	  if (msg->lParam != GTK_WIN32_EMBED_PROTOCOL_VERSION)
Packit 98cdb6
	    g_warning ("GTK Win32 embedding protocol version mismatch, "
Packit 98cdb6
		       "client uses version %d, we understand version %d",
Packit 98cdb6
		       (int) msg->lParam, GTK_WIN32_EMBED_PROTOCOL_VERSION);
Packit 98cdb6
	  if (!socket->plug_window)
Packit 98cdb6
	    {
Packit 98cdb6
	      _gtk_socket_add_window (socket, (GdkNativeWindow) msg->wParam, FALSE);
Packit 98cdb6
	      
Packit 98cdb6
	      if (socket->plug_window)
Packit 98cdb6
		GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: window created"));
Packit 98cdb6
	      
Packit 98cdb6
	      return_val = GDK_FILTER_REMOVE;
Packit 98cdb6
	    }
Packit 98cdb6
	}
Packit 98cdb6
      else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_EVENT_PLUG_MAPPED))
Packit 98cdb6
	{
Packit 98cdb6
	  gboolean was_mapped = socket->is_mapped;
Packit 98cdb6
	  gboolean is_mapped = msg->wParam != 0;
Packit 98cdb6
Packit 98cdb6
	  GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PLUG_MAPPED received is_mapped:%d\n", is_mapped));
Packit 98cdb6
	  if (was_mapped != is_mapped)
Packit 98cdb6
	    {
Packit 98cdb6
	      if (is_mapped)
Packit 98cdb6
		_gtk_socket_handle_map_request (socket);
Packit 98cdb6
	      else
Packit 98cdb6
		{
Packit 98cdb6
		  gdk_window_show (socket->plug_window);
Packit 98cdb6
		  _gtk_socket_unmap_notify (socket);
Packit 98cdb6
		}
Packit 98cdb6
	    }
Packit 98cdb6
	  return_val = GDK_FILTER_REMOVE;
Packit 98cdb6
	}
Packit 98cdb6
      else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_PLUG_RESIZED))
Packit 98cdb6
	{
Packit 98cdb6
	  GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PLUG_RESIZED received\n"));
Packit 98cdb6
	  socket->have_size = FALSE;
Packit 98cdb6
	  gtk_widget_queue_resize (widget);
Packit 98cdb6
	  return_val = GDK_FILTER_REMOVE;
Packit 98cdb6
	}
Packit 98cdb6
      else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_REQUEST_FOCUS))
Packit 98cdb6
	{
Packit 98cdb6
	  GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: REQUEST_FOCUS received\n"));
Packit 98cdb6
	  _gtk_win32_embed_push_message (msg);
Packit 98cdb6
	  _gtk_socket_claim_focus (socket, TRUE);
Packit 98cdb6
	  _gtk_win32_embed_pop_message ();
Packit 98cdb6
	  return_val = GDK_FILTER_REMOVE;
Packit 98cdb6
	}
Packit 98cdb6
      else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_FOCUS_NEXT))
Packit 98cdb6
	{
Packit 98cdb6
	  GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: FOCUS_NEXT received\n"));
Packit 98cdb6
	  _gtk_win32_embed_push_message (msg);
Packit 98cdb6
	  _gtk_socket_advance_toplevel_focus (socket, GTK_DIR_TAB_FORWARD);
Packit 98cdb6
	  _gtk_win32_embed_pop_message ();
Packit 98cdb6
	  return_val = GDK_FILTER_REMOVE;
Packit 98cdb6
	}
Packit 98cdb6
      else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_FOCUS_PREV))
Packit 98cdb6
	{
Packit 98cdb6
	  GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: FOCUS_PREV received\n"));
Packit 98cdb6
	  _gtk_win32_embed_push_message (msg);
Packit 98cdb6
	  _gtk_socket_advance_toplevel_focus (socket, GTK_DIR_TAB_BACKWARD);
Packit 98cdb6
	  _gtk_win32_embed_pop_message ();
Packit 98cdb6
	  return_val = GDK_FILTER_REMOVE;
Packit 98cdb6
	}
Packit 98cdb6
      else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_GRAB_KEY))
Packit 98cdb6
	{
Packit 98cdb6
	  GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: GRAB_KEY received\n"));
Packit 98cdb6
	  _gtk_win32_embed_push_message (msg);
Packit 98cdb6
	  _gtk_socket_add_grabbed_key (socket, msg->wParam, msg->lParam);
Packit 98cdb6
	  _gtk_win32_embed_pop_message ();
Packit 98cdb6
	  return_val = GDK_FILTER_REMOVE;
Packit 98cdb6
	}
Packit 98cdb6
      else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_UNGRAB_KEY))
Packit 98cdb6
	{
Packit 98cdb6
	  GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: UNGRAB_KEY received\n"));
Packit 98cdb6
	  _gtk_win32_embed_push_message (msg);
Packit 98cdb6
	  _gtk_socket_remove_grabbed_key (socket, msg->wParam, msg->lParam);
Packit 98cdb6
	  _gtk_win32_embed_pop_message ();
Packit 98cdb6
	  return_val = GDK_FILTER_REMOVE;
Packit 98cdb6
	}
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return return_val;
Packit 98cdb6
}
Packit 98cdb6