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:
hoa.nguyen%intel.com 2000-04-22 20:39:38 +00:00
Родитель 9d875e83a6
Коммит 1fdb72a9a9
4 изменённых файлов: 553 добавлений и 0 удалений

Просмотреть файл

@ -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__ */