зеркало из https://github.com/mozilla/gecko-dev.git
Adding gtkxtbin library which allows Xt widgets inside a Gtk application.
This is part of a fix for bug #3102 to add legacy plug-in support on linux. -r=blizzard
This commit is contained in:
Родитель
9d875e83a6
Коммит
1fdb72a9a9
|
@ -39,6 +39,7 @@ ifndef MOZ_MONOLITHIC_TOOLKIT
|
|||
|
||||
ifdef MOZ_ENABLE_GTK
|
||||
DIRS += gtksuperwin
|
||||
DIRS += gtkxtbin
|
||||
DIRS += gtk
|
||||
endif
|
||||
|
||||
|
@ -56,6 +57,7 @@ endif
|
|||
|
||||
else
|
||||
ifdef MOZ_ENABLE_GTK
|
||||
DIRS += gtkxtbin
|
||||
DIRS += gtksuperwin
|
||||
endif
|
||||
DIRS += $(MOZ_WIDGET_TOOLKIT)
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
#
|
||||
# Contributor(s): Rusty Lynch (rusty.lynch@intel.com)
|
||||
#
|
||||
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = gtkxtbin
|
||||
LIBRARY_NAME = gtkxtbin
|
||||
|
||||
REQUIRES = gtkxtbin
|
||||
|
||||
CSRCS = \
|
||||
gtkxtbin.c \
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MKSHLIB_FORCE_ALL) \
|
||||
$(SHARED_LIBRARY_LIBS) \
|
||||
$(MKSHLIB_UNFORCE_ALL) \
|
||||
$(NULL)
|
||||
|
||||
ifndef MOZ_MONOLITHIC_TOOLKIT
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_GTK_LDFLAGS)
|
||||
else
|
||||
EXTRA_DSO_LDOPTS += $(TK_LIBS)
|
||||
endif
|
||||
|
||||
EXPORTS = gtkxtbin.h
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifndef MOZ_MONOLITHIC_TOOLKIT
|
||||
CFLAGS += $(MOZ_GTK_CFLAGS)
|
||||
else
|
||||
CFLAGS += $(TK_CFLAGS)
|
||||
endif
|
||||
|
||||
DEFINES += -D_IMPL_NS_WIDGET -DUSE_XIM
|
||||
|
||||
ifeq ($(OS_ARCH), Linux)
|
||||
DEFINES += -D_BSD_SOURCE
|
||||
endif
|
||||
|
||||
INCLUDES += \
|
||||
-I$(srcdir) \
|
||||
$(NULL)
|
||||
|
||||
$(LIBRARY) $(SHARED_LIBRARY): $(SHARED_LIBRARY_LIBS) Makefile
|
||||
|
|
@ -0,0 +1,363 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* GtkXtBin Widget Implementation
|
||||
* Rusty Lynch - 02/27/2000
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The GtkXtBin widget allows for Xt toolkit code to be used
|
||||
* inside a GTK application.
|
||||
*/
|
||||
|
||||
#include "gtkxtbin.h"
|
||||
#include <gdk/gdkx.h>
|
||||
#include <glib.h>
|
||||
#include <assert.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Xlib/Xt stuff */
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Shell.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <X11/StringDefs.h>
|
||||
|
||||
static void gtk_xtbin_class_init (GtkXtBinClass *klass);
|
||||
static void gtk_xtbin_init (GtkXtBin *xtbin);
|
||||
static void gtk_xtbin_realize (GtkWidget *widget);
|
||||
|
||||
static String *fallback = NULL;
|
||||
static int xt_is_initialized = 0;
|
||||
|
||||
static gboolean
|
||||
xt_event_prepare (gpointer source_data,
|
||||
GTimeVal *current_time,
|
||||
gint *timeout,
|
||||
gpointer user_data)
|
||||
{
|
||||
XtAppContext ac;
|
||||
XtInputMask mask;
|
||||
|
||||
ac = XtDisplayToApplicationContext((Display *)user_data);
|
||||
|
||||
GDK_THREADS_ENTER();
|
||||
mask = XtAppPending(ac);
|
||||
GDK_THREADS_LEAVE();
|
||||
|
||||
if (mask)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
xt_event_check (gpointer source_data,
|
||||
GTimeVal *current_time,
|
||||
gpointer user_data)
|
||||
{
|
||||
Display * display;
|
||||
XtAppContext ac;
|
||||
XtInputMask mask;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
|
||||
display = (Display *)user_data;
|
||||
ac = XtDisplayToApplicationContext(display);
|
||||
|
||||
mask = XtAppPending(ac);
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
|
||||
if (mask)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
xt_event_dispatch (gpointer source_data,
|
||||
GTimeVal *current_time,
|
||||
gpointer user_data)
|
||||
{
|
||||
XEvent event;
|
||||
Display * display;
|
||||
XtAppContext ac;
|
||||
XtInputMask mask;
|
||||
|
||||
display = (Display *)user_data;
|
||||
ac = XtDisplayToApplicationContext(display);
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
while((mask = XtAppPending(ac)) > 0)
|
||||
XtAppProcessEvent(ac, mask);
|
||||
GDK_THREADS_LEAVE ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GSourceFuncs xt_event_funcs = {
|
||||
xt_event_prepare,
|
||||
xt_event_check,
|
||||
xt_event_dispatch,
|
||||
(GDestroyNotify)g_free
|
||||
};
|
||||
|
||||
GtkType
|
||||
gtk_xtbin_get_type (void)
|
||||
{
|
||||
static GtkType xtbin_type = 0;
|
||||
|
||||
if (!xtbin_type)
|
||||
{
|
||||
static const GtkTypeInfo xtbin_info =
|
||||
{
|
||||
"GtkXtBin",
|
||||
sizeof (GtkXtBin),
|
||||
sizeof (GtkXtBinClass),
|
||||
(GtkClassInitFunc) gtk_xtbin_class_init,
|
||||
(GtkObjectInitFunc) gtk_xtbin_init,
|
||||
/* reserved_1 */ NULL,
|
||||
/* reserved_2 */ NULL,
|
||||
(GtkClassInitFunc) NULL
|
||||
};
|
||||
|
||||
xtbin_type = gtk_type_unique (GTK_TYPE_WINDOW, &xtbin_info);
|
||||
}
|
||||
|
||||
return xtbin_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_xtbin_class_init (GtkXtBinClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class;
|
||||
|
||||
|
||||
widget_class = GTK_WIDGET_CLASS (klass);
|
||||
widget_class->realize = gtk_xtbin_realize;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_xtbin_init (GtkXtBin *xtbin)
|
||||
{
|
||||
|
||||
xtbin->xtwidget = NULL;
|
||||
xtbin->parent_window = NULL;
|
||||
xtbin->x = 0;
|
||||
xtbin->y = 0;
|
||||
|
||||
xtbin->xtdisplay = NULL;
|
||||
xtbin->xtcontext = 0;
|
||||
xtbin->xtwindow = 0;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_xtbin_realize (GtkWidget *widget)
|
||||
{
|
||||
GdkWindowAttr attributes;
|
||||
gint attributes_mask, n;
|
||||
GtkXtBin *xtbin;
|
||||
Arg args[20];
|
||||
char *mArgv[1];
|
||||
int mArgc = 0;
|
||||
gint width, height;
|
||||
static Display *xtdisplay;
|
||||
XtAppContext app_context;
|
||||
Widget top_widget;
|
||||
Window win;
|
||||
Widget embeded;
|
||||
|
||||
|
||||
g_return_if_fail (GTK_IS_XTBIN (widget));
|
||||
|
||||
gdk_flush();
|
||||
xtbin = GTK_XTBIN (widget);
|
||||
|
||||
/* GtkWindow checks against premature realization here. Just
|
||||
* don't do it.
|
||||
*/
|
||||
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
|
||||
|
||||
attributes.window_type = GDK_WINDOW_CHILD;
|
||||
attributes.x = xtbin->x;
|
||||
attributes.y = xtbin->y;
|
||||
attributes.width = widget->allocation.width;
|
||||
attributes.height = widget->allocation.height;
|
||||
attributes.wclass = GDK_INPUT_OUTPUT;
|
||||
attributes.visual = gtk_widget_get_visual (widget);
|
||||
attributes.colormap = gtk_widget_get_colormap (widget);
|
||||
attributes.event_mask = gtk_widget_get_events (widget);
|
||||
attributes.event_mask |= GDK_EXPOSURE_MASK;
|
||||
attributes_mask = GDK_WA_X | GDK_WA_Y |
|
||||
GDK_WA_VISUAL | GDK_WA_COLORMAP;
|
||||
|
||||
xtbin->width = attributes.width;
|
||||
xtbin->height = attributes.height;
|
||||
|
||||
widget->window = gdk_window_new (xtbin->parent_window,
|
||||
&attributes, attributes_mask);
|
||||
|
||||
/* Turn off any event catching for this window by */
|
||||
/* the Gtk/Gdk event loop... otherwise some strange */
|
||||
/* things happen */
|
||||
XSelectInput(GDK_WINDOW_XDISPLAY(widget->window),
|
||||
GDK_WINDOW_XWINDOW(widget->window),
|
||||
0);
|
||||
|
||||
gdk_window_set_user_data (widget->window, xtbin);
|
||||
|
||||
widget->style = gtk_style_attach (widget->style, widget->window);
|
||||
gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
|
||||
|
||||
xtbin->current_window = widget->window;
|
||||
|
||||
/* ensure all the outgoing events are flushed */
|
||||
/* before we try this crazy dual toolkit stuff */
|
||||
gdk_flush();
|
||||
|
||||
/* Initialize the Xt toolkit */
|
||||
if (!xt_is_initialized) {
|
||||
int cnumber;
|
||||
static GPollFD xt_event_poll_fd;
|
||||
|
||||
/****
|
||||
* Standard Xt initialization stuff
|
||||
*/
|
||||
|
||||
XtToolkitInitialize();
|
||||
app_context = XtCreateApplicationContext();
|
||||
if (fallback)
|
||||
XtAppSetFallbackResources(app_context, fallback);
|
||||
|
||||
xtdisplay = XtOpenDisplay(app_context, NULL, NULL,
|
||||
"Wrapper", NULL, 0, &mArgc, mArgv);
|
||||
xt_is_initialized++;
|
||||
|
||||
/****
|
||||
* hook Xt event loop into the glib event loop.
|
||||
*/
|
||||
|
||||
/* the assumption is that gtk_init has already been called */
|
||||
g_source_add (GDK_PRIORITY_EVENTS, TRUE,
|
||||
&xt_event_funcs, NULL, xtdisplay, NULL);
|
||||
|
||||
cnumber = ConnectionNumber(xtdisplay);
|
||||
xt_event_poll_fd.fd = cnumber;
|
||||
xt_event_poll_fd.events = G_IO_IN | G_IO_OUT;
|
||||
xt_event_poll_fd.revents = 0; /* hmm... is this correct? */
|
||||
|
||||
g_main_add_poll (&xt_event_poll_fd, G_PRIORITY_DEFAULT);
|
||||
}
|
||||
|
||||
/***
|
||||
* I'm sure there is a better way, but for now I'm
|
||||
* just creating a new application shell (since it doesn't
|
||||
* need a parent widget,) and then swapping out the XWindow
|
||||
* from under it. This seems to mostly work, but it's
|
||||
* an ugly hack.
|
||||
*/
|
||||
|
||||
top_widget = XtAppCreateShell("drawingArea", "Wrapper",
|
||||
applicationShellWidgetClass, xtdisplay,
|
||||
NULL, 0);
|
||||
|
||||
|
||||
/* set size of Xt window */
|
||||
n = 0;
|
||||
XtSetArg(args[n], XtNheight, xtbin->height);n++;
|
||||
XtSetArg(args[n], XtNwidth, xtbin->width);n++;
|
||||
XtSetValues(top_widget, args, n);
|
||||
|
||||
embeded = XtVaCreateWidget("form", compositeWidgetClass, top_widget);
|
||||
|
||||
n = 0;
|
||||
XtSetArg(args[n], XtNheight, xtbin->height);n++;
|
||||
XtSetArg(args[n], XtNwidth, xtbin->width);n++;
|
||||
XtSetValues(embeded, args, n);
|
||||
|
||||
/* Ok, here is the dirty little secret on how I am */
|
||||
/* switching the widget's XWindow to the GdkWindow's XWindow. */
|
||||
/* I should be ashamed of myself! */
|
||||
top_widget->core.window = GDK_WINDOW_XWINDOW(widget->window);
|
||||
|
||||
/* this little trick seems to finish initializing the widget */
|
||||
XtRegisterDrawable(xtdisplay,
|
||||
GDK_WINDOW_XWINDOW(widget->window),
|
||||
top_widget);
|
||||
|
||||
XtRealizeWidget(embeded);
|
||||
printf("embeded window = %p\n", XtWindow(embeded));
|
||||
|
||||
XtManageChild(embeded);
|
||||
|
||||
/* now fill out the xtbin info */
|
||||
xtbin->xtdisplay = xtdisplay;
|
||||
xtbin->xtwindow = XtWindow(embeded);
|
||||
|
||||
/* listen to all Xt events */
|
||||
XSelectInput(xtdisplay,
|
||||
XtWindow(top_widget),
|
||||
GDK_ALL_EVENTS_MASK);
|
||||
XSelectInput(xtdisplay,
|
||||
XtWindow(embeded),
|
||||
GDK_ALL_EVENTS_MASK);
|
||||
XFlush(xtdisplay);
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
gtk_xtbin_new (GdkWindow *parent_window, String * f)
|
||||
{
|
||||
GtkXtBin *xtbin;
|
||||
|
||||
assert(parent_window != NULL);
|
||||
|
||||
xtbin = gtk_type_new (GTK_TYPE_XTBIN);
|
||||
xtbin->parent_window = parent_window;
|
||||
if (f)
|
||||
fallback = f;
|
||||
|
||||
return GTK_WIDGET (xtbin);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_xtbin_set_position (GtkXtBin *xtbin,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
xtbin->x = x;
|
||||
xtbin->y = y;
|
||||
|
||||
if (GTK_WIDGET_REALIZED (xtbin))
|
||||
gdk_window_move (GTK_WIDGET (xtbin)->window, x, y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* GtkXtBin Widget Declaration
|
||||
* Rusty Lynch - 02/27/2000
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_XTBIN_H__
|
||||
#define __GTK_XTBIN_H__
|
||||
|
||||
#include <gtk/gtkwindow.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct _GtkXtBin GtkXtBin;
|
||||
typedef struct _GtkXtBinClass GtkXtBinClass;
|
||||
|
||||
#define GTK_TYPE_XTBIN (gtk_xtbin_get_type ())
|
||||
#define GTK_XTBIN(obj) (GTK_CHECK_CAST ((obj), \
|
||||
GTK_TYPE_XTBIN, GtkXtBin))
|
||||
#define GTK_XTBIN_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \
|
||||
GTK_TYPE_XTBIN, GtkXtBinClass))
|
||||
#define GTK_IS_XTBIN(obj) (GTK_CHECK_TYPE ((obj), \
|
||||
GTK_TYPE_XTBIN))
|
||||
#define GTK_IS_XTBIN_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), \
|
||||
GTK_TYPE_XTBIN))
|
||||
|
||||
struct _GtkXtBin
|
||||
{
|
||||
GtkWindow window;
|
||||
GdkWindow *current_window;
|
||||
GdkWindow *parent_window;
|
||||
Widget xtwidget; /* Xt Toolkit Widget */
|
||||
Display *xtdisplay; /* Xt Toolkit Display */
|
||||
XtAppContext xtcontext; /* Xt Toolkit Application Context */
|
||||
Window xtwindow; /* Xt Toolkit XWindow */
|
||||
pthread_t xtEventThread; /* Xt Toolkit Event Loop Thread */
|
||||
gint x, y;
|
||||
gint width, height;
|
||||
};
|
||||
|
||||
struct _GtkXtBinClass
|
||||
{
|
||||
GtkWindowClass window_class;
|
||||
};
|
||||
|
||||
GtkType gtk_xtbin_get_type (void);
|
||||
GtkWidget *gtk_xtbin_new (GdkWindow *parent_window, String *f);
|
||||
void gtk_xtbin_set_position (GtkXtBin *xtbin,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
typedef struct _XtTMRec {
|
||||
XtTranslations translations; /* private to Translation Manager */
|
||||
XtBoundActions proc_table; /* procedure bindings for actions */
|
||||
struct _XtStateRec *current_state; /* Translation Manager state ptr */
|
||||
unsigned long lastEventTime;
|
||||
} XtTMRec, *XtTM;
|
||||
|
||||
typedef struct _CorePart {
|
||||
Widget self; /* pointer to widget itself */
|
||||
WidgetClass widget_class; /* pointer to Widget's ClassRec */
|
||||
Widget parent; /* parent widget */
|
||||
XrmName xrm_name; /* widget resource name quarkified */
|
||||
Boolean being_destroyed; /* marked for destroy */
|
||||
XtCallbackList destroy_callbacks; /* who to call when widget destroyed */
|
||||
XtPointer constraints; /* constraint record */
|
||||
Position x, y; /* window position */
|
||||
Dimension width, height; /* window dimensions */
|
||||
Dimension border_width; /* window border width */
|
||||
Boolean managed; /* is widget geometry managed? */
|
||||
Boolean sensitive; /* is widget sensitive to user events*/
|
||||
Boolean ancestor_sensitive; /* are all ancestors sensitive? */
|
||||
XtEventTable event_table; /* private to event dispatcher */
|
||||
XtTMRec tm; /* translation management */
|
||||
XtTranslations accelerators; /* accelerator translations */
|
||||
Pixel border_pixel; /* window border pixel */
|
||||
Pixmap border_pixmap; /* window border pixmap or NULL */
|
||||
WidgetList popup_list; /* list of popups */
|
||||
Cardinal num_popups; /* how many popups */
|
||||
String name; /* widget resource name */
|
||||
Screen *screen; /* window's screen */
|
||||
Colormap colormap; /* colormap */
|
||||
Window window; /* window ID */
|
||||
Cardinal depth; /* number of planes in window */
|
||||
Pixel background_pixel; /* window background pixel */
|
||||
Pixmap background_pixmap; /* window background pixmap or NULL */
|
||||
Boolean visible; /* is window mapped and not occluded?*/
|
||||
Boolean mapped_when_managed;/* map window if it's managed? */
|
||||
} CorePart;
|
||||
|
||||
typedef struct _WidgetRec {
|
||||
CorePart core;
|
||||
} WidgetRec, CoreRec;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __GTK_XTBIN_H__ */
|
||||
|
Загрузка…
Ссылка в новой задаче