0N/A/*
6447N/A * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A#ifdef HEADLESS
0N/A #error This file should not be included in headless library
0N/A#endif
0N/A
0N/A#include "awt_p.h"
0N/A#include "color.h"
0N/A#include "awt_TopLevel.h"
0N/A#include <X11/IntrinsicP.h>
0N/A#include <X11/Xatom.h>
0N/A#include <X11/Xmd.h>
0N/A#include <X11/Xutil.h>
0N/A#include <X11/Xproto.h>
0N/A#ifndef XAWT
0N/A#include <Xm/MenuShell.h>
0N/A#include <Xm/List.h>
0N/A#include <Xm/Form.h>
0N/A#include <Xm/RowColumn.h>
0N/A#include <Xm/MwmUtil.h>
0N/A#endif /* XAWT */
0N/A#include <jni.h>
0N/A#include <jni_util.h>
0N/A#include <sys/time.h>
0N/A
0N/A#include "awt_xembed.h"
0N/A
0N/A
0N/A#ifndef XAWT
0N/A#if MOTIF_VERSION!=1
0N/A #include <Xm/GrabShell.h>
0N/A#endif
0N/A#endif
0N/A
0N/A#include "java_awt_event_MouseWheelEvent.h"
0N/A
0N/Aextern jint getModifiers(uint32_t state, jint button, jint keyCode);
0N/Aextern jint getButton(uint32_t button);
0N/A
0N/Astatic int32_t winmgr_running = 0;
0N/Astatic Atom OLDecorDelAtom = 0;
0N/Astatic Atom MWMHints = 0;
0N/Astatic Atom DTWMHints = 0;
0N/Astatic Atom decor_list[9];
0N/A
0N/A#ifndef MAX
0N/A#define MAX(a,b) ((a) > (b) ? (a) : (b))
0N/A#endif
0N/A
0N/A#ifndef MIN
0N/A#define MIN(a,b) ((a) < (b) ? (a) : (b))
0N/A#endif
0N/A
0N/A#ifndef XAWT
0N/A/*
0N/A * The following three funtions are to work around menu problems
0N/A */
0N/A
0N/A/*
0N/A * test if there is a menu that has the current focus
0N/A * called from awt_Dialog.c and awt_Component.c
0N/A */
0N/ABoolean
0N/Aawt_util_focusIsOnMenu(Display *display)
0N/A{
0N/A Window window;
0N/A Widget widget;
0N/A int32_t rtr;
0N/A
0N/A XGetInputFocus(display, &window, &rtr);
0N/A if (window == None) {
0N/A return False;
0N/A }
0N/A
0N/A widget = XtWindowToWidget(display, window);
0N/A if (widget == NULL) {
0N/A return False;
0N/A }
0N/A
0N/A if (XtIsSubclass(widget, xmMenuShellWidgetClass)) {
0N/A return True;
0N/A }
0N/A
0N/A #if MOTIF_VERSION!=1
0N/A /* Motif 2.1 uses XmGrabShell on XmComboBox instead
0N/A of XmMenuShell
0N/A */
0N/A if (XtIsSubclass(widget, xmGrabShellWidgetClass)) {
0N/A return True;
0N/A }
0N/A /* Fix 4800638 check the ancestor of focus widget is
0N/A GrabSell
0N/A */
0N/A if (XtIsSubclass(widget, xmListWidgetClass))
0N/A {
0N/A Widget shell = getShellWidget(widget);
0N/A if (shell && XtIsSubclass(shell,
0N/A xmGrabShellWidgetClass))
0N/A {
0N/A return True;
0N/A }
0N/A }
0N/A #endif
0N/A
0N/A if (XtIsSubclass(widget, xmRowColumnWidgetClass)) {
0N/A unsigned char type;
0N/A XtVaGetValues(widget, XmNrowColumnType, &type, NULL);
0N/A if (type == XmMENU_BAR) {
0N/A return True;
0N/A }
0N/A }
0N/A return False;
0N/A}
0N/A
0N/Astatic
0N/Avoid fillButtonEvent(XButtonEvent *ev, int32_t type, Display *display, Window window) {
0N/A ev->type = type;
0N/A ev->display = display;
0N/A ev->window = window;
0N/A ev->send_event = True;
0N/A
0N/A /* REMIND: multi-screen */
0N/A ev->root = RootWindow(display, DefaultScreen(display));
0N/A ev->subwindow = (Window)None;
0N/A ev->time = CurrentTime;
0N/A ev->x = 0;
0N/A ev->y = 0;
0N/A ev->x_root = 0;
0N/A ev->y_root = 0;
0N/A ev->same_screen = True;
0N/A ev->button = Button1;
0N/A ev->state = Button1Mask;
0N/A}
0N/A
0N/A/*
0N/A * generates a mouse press event and a release event
0N/A * called from awt_Dialog.c
0N/A */
0N/Aint32_t
0N/Aawt_util_sendButtonClick(Display *display, Window window)
0N/A{
0N/A XButtonEvent ev;
0N/A int32_t status;
0N/A
0N/A fillButtonEvent(&ev, ButtonPress, display, window);
0N/A status = XSendEvent(display, window, True, ButtonPressMask, (XEvent *)&ev);
0N/A
0N/A if (status != 0) {
0N/A fillButtonEvent(&ev, ButtonRelease, display, window);
0N/A status = XSendEvent(display, window, False, ButtonReleaseMask,
0N/A (XEvent *)&ev);
0N/A }
0N/A return status;
0N/A}
0N/A
0N/AWidget
0N/Aawt_util_createWarningWindow(Widget parent, char *warning)
0N/A{
0N/A Widget warningWindow;
0N/A#ifdef NETSCAPE
0N/A extern Widget FE_MakeAppletSecurityChrome(Widget parent, char* message);
0N/A warningWindow = FE_MakeAppletSecurityChrome(parent, warning);
0N/A#else
0N/A Widget label;
0N/A int32_t argc;
0N/A#define MAX_ARGC 10
0N/A Arg args[MAX_ARGC];
0N/A int32_t screen = 0;
0N/A int32_t i;
0N/A AwtGraphicsConfigDataPtr adata;
0N/A extern int32_t awt_numScreens;
0N/A
0N/A Pixel gray;
0N/A Pixel black;
0N/A
0N/A for (i = 0; i < awt_numScreens; i++) {
0N/A if (ScreenOfDisplay(awt_display, i) == XtScreen(parent)) {
0N/A screen = i;
0N/A break;
0N/A }
0N/A }
0N/A adata = getDefaultConfig(screen);
0N/A
0N/A gray = adata->AwtColorMatch(192, 192, 192, adata);
0N/A black = adata->AwtColorMatch(0, 0, 0, adata);
0N/A
0N/A argc = 0;
0N/A XtSetArg(args[argc], XmNbackground, gray); argc++;
0N/A XtSetArg(args[argc], XmNmarginHeight, 0); argc++;
0N/A XtSetArg(args[argc], XmNmarginWidth, 0); argc++;
0N/A XtSetArg (args[argc], XmNscreen, XtScreen(parent)); argc++;
0N/A
0N/A DASSERT(!(argc > MAX_ARGC));
0N/A warningWindow = XmCreateForm(parent, "main", args, argc);
0N/A
0N/A XtManageChild(warningWindow);
0N/A label = XtVaCreateManagedWidget(warning,
0N/A xmLabelWidgetClass, warningWindow,
0N/A XmNhighlightThickness, 0,
0N/A XmNbackground, gray,
0N/A XmNforeground, black,
0N/A XmNalignment, XmALIGNMENT_CENTER,
0N/A XmNrecomputeSize, False,
0N/A NULL);
0N/A XtVaSetValues(label,
0N/A XmNbottomAttachment, XmATTACH_FORM,
0N/A XmNtopAttachment, XmATTACH_FORM,
0N/A XmNleftAttachment, XmATTACH_FORM,
0N/A XmNrightAttachment, XmATTACH_FORM,
0N/A NULL);
0N/A#endif
0N/A return warningWindow;
0N/A}
0N/A
0N/Avoid
0N/Aawt_setWidgetGravity(Widget w, int32_t gravity)
0N/A{
0N/A XSetWindowAttributes xattr;
0N/A Window win = XtWindow(w);
0N/A
0N/A if (win != None) {
0N/A xattr.bit_gravity = StaticGravity;
0N/A xattr.win_gravity = StaticGravity;
0N/A XChangeWindowAttributes(XtDisplay(w), win,
0N/A CWBitGravity|CWWinGravity,
0N/A &xattr);
0N/A }
0N/A}
0N/A
0N/AWidget get_shell_focused_widget(Widget w) {
0N/A while (w != NULL && !XtIsShell(w)) {
0N/A w = XtParent(w);
0N/A }
0N/A if (w != NULL) {
0N/A return XmGetFocusWidget(w);
0N/A } else {
0N/A return NULL;
0N/A }
0N/A}
0N/A
0N/Avoid
0N/Aawt_util_reshape(Widget w, jint x, jint y, jint wd, jint ht)
0N/A{
0N/A Widget parent;
0N/A Dimension ww, wh;
0N/A Position wx, wy;
0N/A Boolean move = False;
0N/A Boolean resize = False;
0N/A Boolean mapped_when_managed = False;
0N/A Boolean need_to_unmanage = True;
0N/A Widget saved_focus_widget = NULL;
0N/A
0N/A if (w == NULL) {
0N/A JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
0N/A JNU_ThrowNullPointerException(env,"NullPointerException");
0N/A return;
0N/A }
0N/A parent = XtParent(w);
0N/A
0N/A /* Aim: hack to prevent direct children of scrollpane from
0N/A * being unmanaged during a reshape operation (which results
0N/A * in too many expose events).
0N/A */
0N/A if (parent != NULL && XtParent(parent) != NULL &&
0N/A XtIsSubclass(XtParent(parent), xmScrolledWindowWidgetClass)) {
0N/A need_to_unmanage = False;
0N/A }
0N/A
0N/A XtVaGetValues(w,
0N/A XmNwidth, &ww,
0N/A XmNheight, &wh,
0N/A XmNx, &wx,
0N/A XmNy, &wy,
0N/A NULL);
0N/A
0N/A if (x != wx || y != wy) {
0N/A move = True;
0N/A }
0N/A if (wd != ww || ht != wh) {
0N/A resize = True;
0N/A }
0N/A if (!move && !resize) {
0N/A return;
0N/A }
0N/A
0N/A if (need_to_unmanage) {
0N/A if (!resize) {
0N/A mapped_when_managed = w->core.mapped_when_managed;
0N/A w->core.mapped_when_managed = False;
0N/A }
0N/A saved_focus_widget = get_shell_focused_widget(w);
0N/A XtUnmanageChild(w);
0N/A }
0N/A
0N/A /* GES: AVH's hack:
0N/A * Motif ignores attempts to move a toplevel window to 0,0.
0N/A * Instead we set the position to 1,1. The expected value is
0N/A * returned by Frame.getBounds() since it uses the internally
0N/A * held rectangle rather than querying the peer.
0N/A * N.B. [pauly, 9/97] This is only required for wm shells
0N/A * under the Motif Window Manager (MWM), not for any others.
0N/A * Note. Utilizes C short-circuiting if w is not a wm shell.
0N/A */
0N/A if ((x == 0) && (y == 0) &&
0N/A (XtIsSubclass(w, wmShellWidgetClass)) &&
0N/A (XmIsMotifWMRunning(w))) {
0N/A XtVaSetValues(w, XmNx, 1, XmNy, 1, NULL);
0N/A }
0N/A
0N/A if (move && !resize) {
0N/A XtVaSetValues(w, XmNx, x, XmNy, y, NULL);
0N/A
0N/A } else if (resize && !move) {
0N/A XtVaSetValues(w,
0N/A XmNwidth, (wd > 0) ? wd : 1,
0N/A XmNheight, (ht > 0) ? ht : 1,
0N/A NULL);
0N/A
0N/A } else {
0N/A XtVaSetValues(w,
0N/A XmNx, x,
0N/A XmNy, y,
0N/A XmNwidth, (wd > 0) ? wd : 1,
0N/A XmNheight, (ht > 0) ? ht : 1,
0N/A NULL);
0N/A }
0N/A
0N/A if (need_to_unmanage) {
0N/A XtManageChild(w);
0N/A if (!resize) {
0N/A w->core.mapped_when_managed = mapped_when_managed;
0N/A }
0N/A if (saved_focus_widget != NULL) {
0N/A Boolean result = XmProcessTraversal(saved_focus_widget, XmTRAVERSE_CURRENT);
0N/A if (!result)
0N/A {
0N/A Widget shell = saved_focus_widget;
0N/A while(shell != NULL && !XtIsShell(shell)) {
0N/A shell = XtParent(shell);
0N/A }
0N/A XtSetKeyboardFocus(shell, saved_focus_widget);
0N/A }
0N/A }
0N/A }
0N/A}
0N/A
0N/Avoid
0N/Aawt_util_hide(Widget w)
0N/A{
0N/A if (w == NULL) {
0N/A JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
0N/A JNU_ThrowNullPointerException(env,"NullPointerException");
0N/A return;
0N/A }
0N/A XtSetMappedWhenManaged(w, False);
0N/A}
0N/A
0N/Avoid
0N/Aawt_util_show(Widget w)
0N/A{
0N/A/*
0N/A extern Boolean scrollBugWorkAround;
0N/A*/
0N/A if (w == NULL) {
0N/A JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
0N/A JNU_ThrowNullPointerException(env,"NullPointerException");
0N/A return;
0N/A }
0N/A XtSetMappedWhenManaged(w, True);
0N/A/*
0N/A XXX: causes problems on 2.5
0N/A if (!scrollBugWorkAround) {
0N/A awt_setWidgetGravity(w, StaticGravity);
0N/A }
0N/A*/
0N/A}
0N/A
0N/Avoid
0N/Aawt_util_enable(Widget w)
0N/A{
0N/A XtSetSensitive(w, True);
0N/A}
0N/A
0N/Avoid
0N/Aawt_util_disable(Widget w)
0N/A{
0N/A XtSetSensitive(w, False);
0N/A}
0N/A
0N/Avoid
0N/Aawt_util_mapChildren(Widget w, void (*func)(Widget,void *),
0N/A int32_t applyToCurrent, void *data) {
0N/A WidgetList wlist;
0N/A Cardinal wlen = 0;
0N/A Cardinal i;
0N/A
0N/A /* The widget may have been destroyed by another thread. */
0N/A if ((w == NULL) || (!XtIsObject(w)) || (w->core.being_destroyed))
0N/A return;
0N/A
0N/A if (applyToCurrent != 0) {
0N/A (*func)(w, data);
0N/A }
0N/A if (!XtIsComposite(w)) {
0N/A return;
0N/A }
0N/A
0N/A XtVaGetValues(w,
0N/A XmNchildren, &wlist,
0N/A XmNnumChildren, &wlen,
0N/A NULL);
0N/A if (wlen > 0) {
0N/A for (i=0; i < wlen; i++) {
0N/A awt_util_mapChildren(wlist[i], func, 1, data);
0N/A }
0N/A }
0N/A}
0N/A
0N/Avoid
0N/Aawt_changeAttributes(Display *dpy, Widget w, unsigned long mask,
0N/A XSetWindowAttributes *xattr)
0N/A{
0N/A WidgetList wlist;
0N/A Cardinal wlen = 0;
0N/A Cardinal i;
0N/A
0N/A if (XtWindow(w) && XtIsRealized(w)) {
0N/A XChangeWindowAttributes(dpy,
0N/A XtWindow(w),
0N/A mask,
0N/A xattr);
0N/A } else {
0N/A return;
0N/A }
0N/A XtVaGetValues(w,
0N/A XmNchildren, &wlist,
0N/A XmNnumChildren, &wlen,
0N/A NULL);
0N/A for (i = 0; i < wlen; i++) {
0N/A if (XtWindow(wlist[i]) && XtIsRealized(wlist[i])) {
0N/A XChangeWindowAttributes(dpy,
0N/A XtWindow(wlist[i]),
0N/A mask,
0N/A xattr);
0N/A }
0N/A }
0N/A}
0N/A
0N/Astatic Widget prevWgt = NULL;
0N/A
0N/Astatic void
0N/ADestroyCB(Widget w, XtPointer client_data, XtPointer call_data) {
0N/A if (prevWgt == w) {
0N/A prevWgt = NULL;
0N/A }
0N/A}
0N/A
0N/Aint32_t
0N/Aawt_util_setCursor(Widget w, Cursor c) {
0N/A static Cursor prevCur = None;
0N/A
0N/A if (XtIsRealized(w)) {
0N/A unsigned long valuemask = 0;
0N/A XSetWindowAttributes attributes;
0N/A
0N/A valuemask = CWCursor;
0N/A if (prevWgt != NULL) {
0N/A attributes.cursor = None;
0N/A XChangeWindowAttributes(awt_display,
0N/A XtWindow(prevWgt),
0N/A valuemask,
0N/A &attributes);
0N/A }
0N/A
0N/A if (c == None) {
0N/A c = prevCur;
0N/A if (w != NULL) {
0N/A XtAddCallback(w, XmNdestroyCallback, DestroyCB, NULL);
0N/A }
0N/A prevWgt = w;
0N/A } else {
0N/A prevCur = c;
0N/A prevWgt = NULL;
0N/A }
0N/A attributes.cursor = c;
0N/A XChangeWindowAttributes(awt_display,
0N/A XtWindow(w),
0N/A valuemask,
0N/A &attributes);
0N/A XFlush(awt_display);
0N/A return 1;
0N/A } else
0N/A return 0;
0N/A}
0N/A
0N/Avoid
0N/Aawt_util_convertEventTimeAndModifiers(XEvent *event,
0N/A ConvertEventTimeAndModifiers *output) {
0N/A switch (event->type) {
0N/A case KeyPress:
0N/A case KeyRelease:
0N/A output->when = awt_util_nowMillisUTC_offset(event->xkey.time);
0N/A output->modifiers = getModifiers(event->xkey.state, 0, 0);
0N/A break;
0N/A case ButtonPress:
0N/A case ButtonRelease:
0N/A output->when = awt_util_nowMillisUTC_offset(event->xbutton.time);
0N/A output->modifiers = getModifiers(event->xbutton.state,
0N/A getButton(event->xbutton.button), 0);
0N/A break;
0N/A default:
0N/A output->when = awt_util_nowMillisUTC();
0N/A output->modifiers =0;
0N/A break;
0N/A }
0N/A}
0N/A
0N/A
0N/A/*
0N/A Part fix for bug id 4017222. Return the widget at the given screen coords
0N/A by searching the widget tree beginning at root. This function will return
0N/A null if the pointer is not over the root widget or child of the root widget.
0N/A
0N/A Additionally, this function will only return a Widget with non-nil XmNuserData.
0N/A In 1.2.1, when the mouse was dragged over a Choice component, this function
0N/A returned the GadgetButton associated with the Choice. This GadgetButton had
0N/A nil as its XmNuserData. This lead to a crash when the nil XmNuserData was
0N/A extracted and used as a reference to a peer. Ooops.
0N/A Now the GadgetButton is not returned and the function goes on to find a widget
0N/A which contains the correct peer reference in XmNuserData.
0N/A*/
0N/AWidget
0N/Aawt_WidgetAtXY(Widget root, Position pointerx, Position pointery) {
0N/A Widget answer = NULL;
0N/A
0N/A if(!root) return NULL;
0N/A
0N/A if(XtIsComposite(root)) {
0N/A int32_t i=0;
0N/A WidgetList wl=NULL;
0N/A Cardinal wlen=0;
0N/A
0N/A XtVaGetValues(root, XmNchildren, &wl, XmNnumChildren, &wlen, NULL);
0N/A
0N/A if(wlen>0) {
0N/A for(i=0; i<wlen && !answer; i++) {
0N/A answer = awt_WidgetAtXY(wl[i], pointerx, pointery);
0N/A }
0N/A }
0N/A }
0N/A
0N/A if(!answer) {
0N/A Position wx=0, wy=0;
0N/A Dimension width=0, height=0;
0N/A int32_t lastx=0, lasty=0;
0N/A XtPointer widgetUserData=NULL;
0N/A
0N/A XtVaGetValues(root, XmNwidth, &width, XmNheight, &height,
0N/A XmNuserData, &widgetUserData,
0N/A NULL);
0N/A
0N/A XtTranslateCoords(root, 0, 0, &wx, &wy);
0N/A lastx = wx + width;
0N/A lasty = wy + height;
0N/A
0N/A if(pointerx>=wx && pointerx<=lastx && pointery>=wy && pointery<=lasty &&
0N/A widgetUserData)
0N/A answer = root;
0N/A }
0N/A
0N/A return answer;
0N/A}
0N/A#ifdef __linux__
0N/A
0N/A
0N/A#define MAXARGS 10
0N/Astatic Arg xic_vlist[MAXARGS];
0N/Astatic Arg status_vlist[MAXARGS];
0N/Astatic Arg preedit_vlist[MAXARGS];
0N/A
0N/A#define NO_ARG_VAL -1
0N/A#define SEPARATOR_HEIGHT 2
0N/A
0N/Astatic XFontSet extract_fontset(XmFontList);
0N/A
0N/A/* get_im_height: returns height of the input method status area in pixels.
0N/A *
0N/A * This function assumes that if any XIM related information cannot be
0N/A * queried then the app must not have an input method status area in the
0N/A * current locale and returns zero as the status area height
0N/A */
0N/A
0N/Astatic XtPointer*
0N/Aget_im_info_ptr(Widget w,
0N/A Boolean create)
0N/A{
0N/A Widget p;
0N/A XmVendorShellExtObject ve;
0N/A XmWidgetExtData extData;
0N/A XmImShellInfo im_info;
0N/A XmImDisplayInfo xim_info;
0N/A
0N/A if (w == NULL)
0N/A return NULL;
0N/A
0N/A p = w;
0N/A while (!XtIsShell(p))
0N/A p = XtParent(p);
0N/A
0N/A /* Check extension data since app could be attempting to create
0N/A * a text widget as child of menu shell. This is illegal, and will
0N/A * be detected later, but check here so we don't core dump.
0N/A */
0N/A if ((extData = _XmGetWidgetExtData((Widget)p, XmSHELL_EXTENSION)) == NULL)
0N/A return NULL;
0N/A
0N/A ve = (XmVendorShellExtObject) extData->widget;
0N/A
0N/A return &ve->vendor.im_info;
0N/A}
0N/A
0N/Astatic XmImShellInfo
0N/Aget_im_info(Widget w,
0N/A Boolean create)
0N/A{
0N/A XmImShellInfo* ptr = (XmImShellInfo *) get_im_info_ptr(w, create);
0N/A if (ptr != NULL)
0N/A return *ptr;
0N/A else
0N/A return NULL;
0N/A}
0N/A
0N/A#endif /* !linux */
0N/A
0N/AWidget
0N/Aawt_util_getXICStatusAreaWindow(Widget w)
0N/A{
0N/A while (!XtIsShell(w)){
0N/A w = XtParent(w);
0N/A }
0N/A return w;
0N/A}
0N/A
0N/A#ifdef __linux__
0N/Astatic XRectangle geometryRect;
0N/AXVaNestedList awt_util_getXICStatusAreaList(Widget w)
0N/A{
0N/A XIC xic;
0N/A XmImXICInfo icp;
0N/A XmVendorShellExtObject ve;
0N/A XmWidgetExtData extData;
0N/A XmImShellInfo im_info;
0N/A XmFontList fl=NULL;
0N/A
0N/A XRectangle *ssgeometry = &geometryRect;
0N/A XRectangle geomRect ;
0N/A XRectangle *im_rect;
0N/A XFontSet *im_font;
0N/A
0N/A Pixel bg ;
0N/A Pixel fg ;
0N/A Dimension height, width ;
0N/A Position x,y ;
0N/A Pixmap bpm, *bpmout ;
0N/A
0N/A XVaNestedList list = NULL;
0N/A
0N/A char *ret;
0N/A Widget p=w;
0N/A
0N/A while (!XtIsShell(p)) {
0N/A p = XtParent(p);
0N/A }
0N/A
0N/A XtVaGetValues(p,
0N/A XmNx, &x,
0N/A XmNy, &y,
0N/A XmNwidth, &width,
0N/A XmNheight, &height,
0N/A XmNbackgroundPixmap, &bpm,
0N/A NULL);
0N/A
0N/A extData = _XmGetWidgetExtData((Widget) p, XmSHELL_EXTENSION);
0N/A if (extData == NULL) {
0N/A return NULL;
0N/A }
0N/A ve = (XmVendorShellExtObject) extData->widget;
0N/A im_info = get_im_info(w, False);
0N/A
0N/A if (im_info == NULL) {
0N/A return NULL;
0N/A } else {
0N/A icp = im_info->iclist;
0N/A }
0N/A
0N/A if (icp) {
0N/A /*
0N/A * We have at least a textfield/textarea in the frame, use the
0N/A * first one.
0N/A */
0N/A ssgeometry->x = 0;
0N/A ssgeometry->y = height - icp->sp_height;
0N/A ssgeometry->width = icp->status_width;
0N/A ssgeometry->height = icp->sp_height;
0N/A XtVaGetValues(w, XmNbackground, &bg, NULL);
0N/A XtVaGetValues(w, XmNforeground, &fg, NULL);
0N/A XtVaGetValues(w, XmNfontList, &fl, NULL);
0N/A /*
0N/A * use motif TextComponent's resource
0N/A */
0N/A
0N/A list = XVaCreateNestedList(0,
0N/A XNFontSet, extract_fontset(fl),
0N/A XNArea, ssgeometry,
0N/A XNBackground, bg,
0N/A XNForeground, fg,
0N/A NULL);
0N/A }
0N/A return list ;
0N/A}
0N/A
0N/Astatic XFontSet
0N/Aextract_fontset(XmFontList fl)
0N/A{
0N/A XmFontContext context;
0N/A XmFontListEntry next_entry;
0N/A XmFontType type_return;
0N/A XtPointer tmp_font;
0N/A XFontSet first_fs = NULL;
0N/A char *font_tag;
0N/A
0N/A if (!XmFontListInitFontContext(&context, fl))
0N/A return NULL;
0N/A
0N/A do {
0N/A next_entry = XmFontListNextEntry(context);
0N/A if (next_entry) {
0N/A tmp_font = XmFontListEntryGetFont(next_entry, &type_return);
0N/A if (type_return == XmFONT_IS_FONTSET) {
0N/A font_tag = XmFontListEntryGetTag(next_entry);
0N/A if (!strcmp(font_tag, XmFONTLIST_DEFAULT_TAG)) {
0N/A XmFontListFreeFontContext(context);
0N/A XtFree(font_tag);
0N/A return (XFontSet) tmp_font;
0N/A }
0N/A XtFree(font_tag);
0N/A if (first_fs == NULL)
0N/A first_fs = (XFontSet) tmp_font;
0N/A }
0N/A }
0N/A } while (next_entry);
0N/A
0N/A XmFontListFreeFontContext(context);
0N/A return first_fs;
0N/A}
0N/A#endif
0N/A
0N/A/*the caller does have the responsibility to free the memory return
0N/A from this function...*/
0N/Achar* awt_util_makeWMMenuItem(char *target, Atom protocol){
0N/A char *buf = NULL;
0N/A int32_t buflen = 0;
0N/A
0N/A /*a label in a menuitem is not supposed to be a FullOfSpaceString... */
0N/A buflen = strlen(target) * 3;
0N/A buf = (char*)malloc(buflen + 20);
0N/A if (buf == NULL){
0N/A JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL);
0N/A }
0N/A else{
0N/A int32_t off = 0;
0N/A char *ptr = target;
0N/A while ((off < (buflen - 20)) && (*ptr != '\0')){
0N/A if (*ptr == ' '){
0N/A *(buf + off++) = 0x5c;
0N/A }
0N/A *(buf + off++) = *ptr++;
0N/A }
0N/A sprintf(buf + off, " f.send_msg %ld", protocol);
0N/A }
0N/A return buf;
0N/A}
0N/A
0N/A/*
0N/A * This callback proc is installed via setting the XmNinsertPosition
0N/A * resource on a widget. It ensures that components added
0N/A * to a widget are inserted in the correct z-order position
0N/A * to match up with their peer/target ordering in Container.java
0N/A */
0N/ACardinal
0N/Aawt_util_insertCallback(Widget w)
0N/A{
0N/A jobject peer;
0N/A WidgetList children;
0N/A Cardinal num_children;
0N/A Widget parent;
0N/A XtPointer userdata;
0N/A Cardinal index;
0N/A int32_t pos;
0N/A JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
0N/A
0N/A parent = XtParent(w);
0N/A XtVaGetValues(parent,
0N/A XmNnumChildren, &num_children,
0N/A XmNchildren, &children,
0N/A NULL);
0N/A XtVaGetValues(w, XmNuserData, &userdata, NULL);
0N/A
0N/A index = num_children; /* default is to add to end */
0N/A
0N/A if (userdata != NULL) {
0N/A peer = (jobject) userdata;
0N/A
0N/A // SECURITY: We are running on the privileged toolkit thread.
0N/A // The peer must *NOT* call into user code
0N/A pos = (int32_t) JNU_CallMethodByName(env
0N/A ,NULL
0N/A ,(jobject) peer
0N/A ,"getZOrderPosition_NoClientCode"
0N/A ,"()I").i;
0N/A if ((*env)->ExceptionOccurred(env)) {
0N/A (*env)->ExceptionDescribe(env);
0N/A (*env)->ExceptionClear(env);
0N/A }
0N/A index = (Cardinal) (pos != -1 ? pos : num_children);
0N/A }
0N/A return index;
0N/A}
0N/A
0N/Avoid
0N/Aawt_util_consumeAllXEvents(Widget widget)
0N/A{
0N/A /* Remove all queued X Events for the window of the widget. */
0N/A
0N/A#define ALL_EVENTS_MASK 0xFFFF
0N/A
0N/A XEvent xev;
0N/A
0N/A XFlush(awt_display);
0N/A while (XCheckWindowEvent(awt_display, XtWindow(widget),
0N/A ALL_EVENTS_MASK, &xev)) ;
0N/A}
0N/A
0N/A#endif /* XAWT */
0N/A/**
0N/A * Gets the thread we are currently executing on
0N/A */
0N/Ajobject
0N/AawtJNI_GetCurrentThread(JNIEnv *env) {
0N/A static jclass threadClass = NULL;
0N/A static jmethodID currentThreadMethodID = NULL;
0N/A
0N/A jobject currentThread = NULL;
0N/A
0N/A /* Initialize our java identifiers once. Checking before locking
0N/A * is a huge performance win.
0N/A */
0N/A if (threadClass == NULL) {
0N/A // should enter a monitor here...
0N/A Boolean err = FALSE;
0N/A if (threadClass == NULL) {
0N/A jclass tc = (*env)->FindClass(env, "java/lang/Thread");
0N/A threadClass = (*env)->NewGlobalRef(env, tc);
0N/A if (threadClass != NULL) {
0N/A currentThreadMethodID = (*env)->GetStaticMethodID(env,
0N/A threadClass,
0N/A "currentThread",
0N/A "()Ljava/lang/Thread;"
0N/A );
0N/A }
0N/A }
0N/A if (currentThreadMethodID == NULL) {
0N/A threadClass = NULL;
0N/A err = TRUE;
0N/A }
0N/A if (err) {
0N/A return NULL;
0N/A }
0N/A } /* threadClass == NULL*/
0N/A
0N/A currentThread = (*env)->CallStaticObjectMethod(
0N/A env, threadClass, currentThreadMethodID);
0N/A DASSERT(!((*env)->ExceptionOccurred(env)));
0N/A /*JNU_PrintString(env, "getCurrentThread() -> ", JNU_ToString(env,currentThread));*/
0N/A return currentThread;
0N/A} /* awtJNI_GetCurrentThread() */
0N/A
0N/Avoid
0N/AawtJNI_ThreadYield(JNIEnv *env) {
0N/A
0N/A static jclass threadClass = NULL;
0N/A static jmethodID yieldMethodID = NULL;
0N/A
0N/A /* Initialize our java identifiers once. Checking before locking
0N/A * is a huge performance win.
0N/A */
0N/A if (threadClass == NULL) {
0N/A // should enter a monitor here...
0N/A Boolean err = FALSE;
0N/A if (threadClass == NULL) {
0N/A jclass tc = (*env)->FindClass(env, "java/lang/Thread");
0N/A threadClass = (*env)->NewGlobalRef(env, tc);
0N/A (*env)->DeleteLocalRef(env, tc);
0N/A if (threadClass != NULL) {
0N/A yieldMethodID = (*env)->GetStaticMethodID(env,
0N/A threadClass,
0N/A "yield",
0N/A "()V"
0N/A );
0N/A }
0N/A }
0N/A if (yieldMethodID == NULL) {
0N/A threadClass = NULL;
0N/A err = TRUE;
0N/A }
0N/A if (err) {
0N/A return;
0N/A }
0N/A } /* threadClass == NULL*/
0N/A
0N/A (*env)->CallStaticVoidMethod(env, threadClass, yieldMethodID);
0N/A DASSERT(!((*env)->ExceptionOccurred(env)));
0N/A} /* awtJNI_ThreadYield() */
0N/A
0N/A#ifndef XAWT
0N/A
0N/Avoid
0N/Aawt_util_cleanupBeforeDestroyWidget(Widget widget)
0N/A{
0N/A /* Bug 4017222: Drag processing uses global prevWidget. */
0N/A if (widget == prevWidget) {
0N/A prevWidget = NULL;
0N/A }
0N/A}
0N/A
0N/Astatic Boolean timeStampUpdated = False;
0N/A
0N/Astatic int32_t
0N/AisTimeStampUpdated(void* p) {
0N/A return timeStampUpdated;
0N/A}
0N/A
0N/Astatic void
0N/ApropertyChangeEventHandler(Widget w, XtPointer client_data,
0N/A XEvent* event, Boolean* continue_to_dispatch) {
0N/A timeStampUpdated = True;
0N/A}
0N/A
0N/A/*
0N/A * If the application doesn't receive events with timestamp for a long time
0N/A * XtLastTimestampProcessed() will return out-of-date value. This may cause
0N/A * selection handling routines to fail (see BugTraq ID 4085183).
0N/A * This routine is to resolve this problem. It queries the current X server
0N/A * time by appending a zero-length data to a property as prescribed by
0N/A * X11 Reference Manual.
0N/A * Note that this is a round-trip request, so it can be slow. If you know
0N/A * that the Xt timestamp is up-to-date use XtLastTimestampProcessed().
0N/A */
0N/ATime
0N/Aawt_util_getCurrentServerTime() {
0N/A
0N/A JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
0N/A static Atom _XA_JAVA_TIME_PROPERTY_ATOM = 0;
0N/A Time server_time = 0;
0N/A
0N/A AWT_LOCK();
0N/A
0N/A if (_XA_JAVA_TIME_PROPERTY_ATOM == 0) {
0N/A XtAddEventHandler(awt_root_shell, PropertyChangeMask, False,
0N/A propertyChangeEventHandler, NULL);
0N/A _XA_JAVA_TIME_PROPERTY_ATOM = XInternAtom(awt_display, "_SUNW_JAVA_AWT_TIME", False);
0N/A }
0N/A
0N/A timeStampUpdated = False;
0N/A XChangeProperty(awt_display, XtWindow(awt_root_shell),
0N/A _XA_JAVA_TIME_PROPERTY_ATOM, XA_ATOM, 32, PropModeAppend,
0N/A (unsigned char *)"", 0);
0N/A XFlush(awt_display);
0N/A
0N/A if (awt_currentThreadIsPrivileged(env)) {
0N/A XEvent event;
0N/A XMaskEvent(awt_display, PropertyChangeMask, &event);
0N/A XtDispatchEvent(&event);
0N/A } else {
0N/A awt_MToolkit_modalWait(isTimeStampUpdated, NULL);
0N/A }
0N/A server_time = XtLastTimestampProcessed(awt_display);
0N/A
0N/A AWT_UNLOCK();
0N/A
0N/A return server_time;
0N/A}
0N/A
0N/A/*
0N/A * This function is stolen from /src/solaris/hpi/src/system_md.c
0N/A * It is used in setting the time in Java-level InputEvents
0N/A */
0N/Ajlong
0N/Aawt_util_nowMillisUTC()
0N/A{
0N/A struct timeval t;
0N/A gettimeofday(&t, NULL);
0N/A return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000);
0N/A}
0N/A
0N/A/*
0N/A * This function converts between the X server time (number of milliseconds
0N/A * since the last server reset) and the UTC time for the 'when' field of an
0N/A * InputEvent (or another event type with a timestamp).
0N/A */
0N/Ajlong
0N/Aawt_util_nowMillisUTC_offset(Time server_offset)
0N/A{
0N/A /*
0N/A * Because Time is of type 'unsigned long', it is possible that Time will
0N/A * never wrap when using 64-bit Xlib. However, if a 64-bit client
0N/A * connects to a 32-bit server, I suspect the values will still wrap. So
0N/A * we should not attempt to remove the wrap checking even if _LP64 is
0N/A * true.
0N/A */
0N/A static const jlong WRAP_TIME_MILLIS = (jlong)((uint32_t)-1);
0N/A static jlong reset_time_utc;
0N/A
0N/A jlong current_time_utc = awt_util_nowMillisUTC();
0N/A
0N/A if ((current_time_utc - reset_time_utc) > WRAP_TIME_MILLIS) {
0N/A reset_time_utc = awt_util_nowMillisUTC() -
0N/A awt_util_getCurrentServerTime();
0N/A }
0N/A
0N/A return reset_time_utc + server_offset;
0N/A}
0N/A
0N/Avoid awt_util_do_wheel_scroll(Widget scrolled_window, jint scrollType,
0N/A jint scrollAmt, jint wheelAmt) {
0N/A Widget scrollbar = NULL;
0N/A int value;
0N/A int slider_size;
0N/A int min;
0N/A int max;
0N/A int increment;
0N/A int page_increment;
0N/A int scrollAdjustment;
0N/A int newValue;
0N/A
0N/A /* TODO:
0N/A * If a TextArea's scrollbar policy is set to never, it should still
0N/A * wheel scroll, but right now it doesn't.
0N/A */
0N/A
0N/A scrollbar = awt_util_get_scrollbar_to_scroll(scrolled_window);
0N/A if (scrollbar == NULL) { /* no suitable scrollbar for scrolling */
0N/A return;
0N/A }
0N/A
0N/A XtVaGetValues(scrollbar, XmNvalue, &value,
0N/A XmNsliderSize, &slider_size,
0N/A XmNminimum, &min,
0N/A XmNmaximum, &max,
0N/A XmNincrement, &increment,
0N/A XmNpageIncrement, &page_increment, NULL);
0N/A
0N/A if (scrollType == java_awt_event_MouseWheelEvent_WHEEL_BLOCK_SCROLL) {
0N/A scrollAdjustment = page_increment;
0N/A }
0N/A else { // WHEEL_UNIT_SCROLL
0N/A scrollAdjustment = increment * scrollAmt;
0N/A }
0N/A
0N/A if (wheelAmt < 0) {
0N/A // Don't need to check that newValue < max - slider_size because
0N/A // newValue < current value. If scrollAmt is ever user-configurable,
0N/A // we'll have to check this.
0N/A newValue = MAX(min, value+ (scrollAdjustment * wheelAmt));
0N/A }
0N/A else {
0N/A newValue = MIN(max - slider_size,
0N/A value + (scrollAdjustment * wheelAmt));
0N/A }
0N/A
0N/A XtVaSetValues(scrollbar, XmNvalue, newValue, NULL);
0N/A XtCallCallbacks(scrollbar, XmNvalueChangedCallback, NULL);
0N/A}
0N/A
0N/A
0N/A/* Given a ScrollWindow widget, return the Scrollbar that the wheel should
0N/A * scroll. A null return value means that the ScrollWindow has a scrollbar
0N/A * display policy of none, or that neither scrollbar can be scrolled.
0N/A */
0N/AWidget awt_util_get_scrollbar_to_scroll(Widget scrolled_window) {
0N/A Widget scrollbar = NULL;
0N/A int value;
0N/A int slider_size;
0N/A int min;
0N/A int max;
0N/A
0N/A /* first, try the vertical scrollbar */
0N/A XtVaGetValues(scrolled_window, XmNverticalScrollBar, &scrollbar, NULL);
0N/A if (scrollbar != NULL) {
0N/A XtVaGetValues(scrollbar, XmNvalue, &value,
0N/A XmNsliderSize, &slider_size,
0N/A XmNminimum, &min,
0N/A XmNmaximum, &max, NULL);
0N/A if (slider_size < max - min) {
0N/A return scrollbar;
0N/A }
0N/A }
0N/A
0N/A /* then, try the horiz */
0N/A XtVaGetValues(scrolled_window, XmNhorizontalScrollBar, &scrollbar, NULL);
0N/A if (scrollbar != NULL) {
0N/A XtVaGetValues(scrollbar, XmNvalue, &value,
0N/A XmNsliderSize, &slider_size,
0N/A XmNminimum, &min,
0N/A XmNmaximum, &max, NULL);
0N/A if (slider_size < max - min) {
0N/A return scrollbar;
0N/A }
0N/A }
0N/A /* neither is suitable for scrolling */
0N/A return NULL;
0N/A}
0N/A
0N/AEmbeddedFrame *theEmbeddedFrameList = NULL;
0N/A
0N/Astatic void awt_util_updateXtCoordinatesForEmbeddedFrame(Widget ef)
0N/A{
0N/A Window ef_window;
0N/A Window win;
0N/A int32_t x, y;
0N/A ef_window = XtWindow(ef);
0N/A if (ef_window != None) {
0N/A if (XTranslateCoordinates(awt_display, ef_window,
0N/A RootWindowOfScreen(XtScreen(ef)),
0N/A 0, 0, &x, &y, &win)) {
0N/A DTRACE_PRINTLN("correcting coordinates");
0N/A ef->core.x = x;
0N/A ef->core.y = y;
0N/A }
0N/A }
0N/A}
0N/A
0N/ABoolean awt_util_processEventForEmbeddedFrame(XEvent *ev)
0N/A{
0N/A EmbeddedFrame *ef;
0N/A Boolean dummy;
0N/A Boolean eventProcessed = False;
0N/A switch (ev->type) {
0N/A case FocusIn:
0N/A case FocusOut:
0N/A ef = theEmbeddedFrameList;
0N/A while (ef != NULL) {
0N/A if (ef->frameContainer == ev->xfocus.window) {
0N/A eventProcessed = True;
0N/A if (isXEmbedActiveByWindow(XtWindow(ef->embeddedFrame))) {
0N/A return True;
0N/A }
0N/A // pretend that the embedded frame gets a focus event
0N/A // the event's window field is not the same as
0N/A // the embeddedFrame's widget, but luckily the shellEH
0N/A // doesnt seem to care about this.
0N/A shellEH(ef->embeddedFrame, ef->javaRef, ev, &dummy);
0N/A }
0N/A ef = ef->next;
0N/A }
0N/A return eventProcessed;
0N/A case ConfigureNotify:
0N/A for (ef = theEmbeddedFrameList; ef != NULL; ef = ef->next) {
0N/A awt_util_updateXtCoordinatesForEmbeddedFrame(ef->embeddedFrame);
0N/A }
0N/A return True;
0N/A }
0N/A return False;
0N/A}
0N/A
0N/Avoid awt_util_addEmbeddedFrame(Widget embeddedFrame, jobject javaRef)
0N/A{
0N/A EmbeddedFrame *ef, *eflist;
0N/A Atom WM_STATE;
0N/A Window win;
0N/A Window parent, root;
0N/A Window *children;
0N/A uint32_t nchildren;
0N/A Atom type = None;
0N/A int32_t format;
0N/A unsigned long nitems, after;
0N/A unsigned char * data;
0N/A XWindowAttributes win_attributes;
0N/A
0N/A WM_STATE = XInternAtom(awt_display, "WM_STATE", True);
0N/A if (WM_STATE == None) {
0N/A return;
0N/A }
0N/A win = XtWindow(embeddedFrame);
0N/A if (win == None)
0N/A return;
0N/A /*
0N/A * according to XICCM, we search our toplevel window
0N/A * by looking for WM_STATE property
0N/A */
0N/A while (True) {
0N/A if (!XQueryTree(awt_display, win, &root, &parent,
0N/A &children, &nchildren)) {
0N/A return;
0N/A }
0N/A if (children) {
0N/A XFree(children);
0N/A }
0N/A if (parent == NULL || parent == root) {
0N/A return;
0N/A }
0N/A win = parent;
0N/A /*
0N/A * Add StructureNotifyMask through hierarchy upto toplevel
0N/A */
0N/A XGetWindowAttributes(awt_display, win, &win_attributes);
0N/A XSelectInput(awt_display, win, win_attributes.your_event_mask |
0N/A StructureNotifyMask);
0N/A
0N/A if (XGetWindowProperty(awt_display, win, WM_STATE,
0N/A 0, 0, False, AnyPropertyType,
0N/A &type, &format, &nitems, &after, &data) == Success) {
0N/A XFree(data);
0N/A if (type) {
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A ef = (EmbeddedFrame *) malloc(sizeof(EmbeddedFrame));
0N/A if (ef == NULL) {
0N/A JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2),
0N/A "OutOfMemory in awt_util_addEmbeddedFrame");
0N/A return;
0N/A }
0N/A ef->embeddedFrame = embeddedFrame;
0N/A ef->frameContainer = win;
0N/A ef->javaRef = javaRef;
0N/A ef->eventSelectedPreviously = False;
0N/A /* initialize the xt coordinates */
0N/A awt_util_updateXtCoordinatesForEmbeddedFrame(embeddedFrame);
0N/A
0N/A /*
0N/A * go through the exisiting embedded frames see if we have
0N/A * already selected the event on the same frameContainer
0N/A */
0N/A eflist = theEmbeddedFrameList;
0N/A while (eflist != NULL) {
0N/A if (eflist->frameContainer == win) {
0N/A break;
0N/A }
0N/A eflist = eflist->next;
0N/A }
0N/A if (eflist != NULL) {
0N/A /*
0N/A * we already have a embedded frame selecting this container's
0N/A * event, we remember its eventSelectedPreviously value
0N/A * so that we know whether to deselect later when we are removed
0N/A */
0N/A ef->eventSelectedPreviously = eflist->eventSelectedPreviously;
0N/A } else {
0N/A XGetWindowAttributes(awt_display, ef->frameContainer,
0N/A &win_attributes);
0N/A XSelectInput(awt_display, ef->frameContainer,
0N/A win_attributes.your_event_mask | FocusChangeMask);
0N/A }
0N/A
0N/A /* ef will become the head of the embedded frame list */
0N/A ef->next = theEmbeddedFrameList;
0N/A if (theEmbeddedFrameList != NULL) {
0N/A theEmbeddedFrameList->prev = ef;
0N/A }
0N/A ef->prev = NULL;
0N/A theEmbeddedFrameList = ef;
0N/A}
0N/A
0N/Avoid awt_util_delEmbeddedFrame(Widget embeddedFrame)
0N/A{
0N/A EmbeddedFrame *ef = theEmbeddedFrameList;
0N/A Window frameContainer;
0N/A XWindowAttributes win_attributes;
0N/A Boolean needToDeselect;
0N/A
0N/A while (ef != NULL) {
0N/A if (ef->embeddedFrame == embeddedFrame) {
0N/A break;
0N/A }
0N/A ef = ef->next;
0N/A }
0N/A if (ef == NULL) { /* cannot find specified embedded frame */
0N/A return;
0N/A }
0N/A /* remove ef from link list EmbeddedFrameList */
0N/A if (ef->prev) {
0N/A ef->prev->next = ef->next;
0N/A }
0N/A if (ef->next) {
0N/A ef->next->prev = ef->prev;
0N/A }
0N/A if (theEmbeddedFrameList == ef) {
0N/A theEmbeddedFrameList = ef->next;
0N/A }
0N/A
0N/A frameContainer = ef->frameContainer;
0N/A needToDeselect = ef->eventSelectedPreviously ? False : True;
0N/A free(ef);
0N/A if (!needToDeselect) {
0N/A return;
0N/A }
0N/A /*
0N/A * now decide whether we need to stop listenning event for
0N/A * frameContainer
0N/A */
0N/A ef = theEmbeddedFrameList;
0N/A while (ef != NULL) {
0N/A if (ef->frameContainer == frameContainer) {
0N/A break;
0N/A }
0N/A ef = ef->next;
0N/A }
0N/A if (ef == NULL) {
0N/A /*
0N/A * if we get here, no one is interested in this frame
0N/A * and StructureNotify was not selected by anyone else
0N/A * so we deselect it
0N/A */
0N/A DTRACE_PRINTLN("remove event from frame");
0N/A XGetWindowAttributes(awt_display, frameContainer, &win_attributes);
0N/A XSelectInput(awt_display, frameContainer,
0N/A win_attributes.your_event_mask &
0N/A (~FocusChangeMask));
0N/A }
0N/A}
0N/A
0N/A#endif /* XAWT */
0N/A
0N/Avoid awt_util_debug_init() {
0N/A#if defined(DEBUG)
0N/A DTrace_Initialize();
0N/A#endif
0N/A}
0N/A
0N/Astatic void awt_util_debug_fini() {
0N/A#if defined(DEBUG)
0N/A DTrace_Shutdown();
0N/A#endif
0N/A}