📄 wnd.c
字号:
/** * wnd.c - native toplevel window related functions * * Copyright (c) 1998 * Transvirtual Technologies, Inc. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */#include <limits.h>#include <X11/Xlib.h>#include <X11/cursorfont.h>#include <X11/Xutil.h>#include "toolkit.h"long StdEvents = ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | /* PointerMotionHintMask | */ ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask | StructureNotifyMask | FocusChangeMask | VisibilityChangeMask;long PopupEvents = ExposureMask | PointerMotionMask | /* PointerMotionHintMask | */ ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask | StructureNotifyMask | VisibilityChangeMask;/* * X dosen't have "owned" popups (menus, choice windows etc.), all it has * are 'isTransientFor' properties, and these might not be honored by native * window managers in a way that the popup, when getting the focus, doesn't * visibly take the focus away from the owner ("shading" its titlebar). The * only reliable, non wm-dependent way to prevent this seems to be not to select * key events for the popup (i.e. not giving it the focus at all). But we don't * want to let this native layer deficiency (of a single platform) show up on * the Java side. We implement these temporary popup focus shifts by means of * focus forwarding in the native layer, which means we have to take care of * propper forwarding/restore during setVisible/requestFocus/destroy, and * focus/key events. The owner never gives up the focus with respect to X, * but the native layer keeps track of all the involved retargeting of * Java events, thus giving Java the illusion of a real focus switch. * Since this comes with some "artificial" events we have * to process in the Java event queue, we use ClientMessages mapped to the * corresponding Java FocusEvents. *//* also used in evt.c */void forwardFocus ( int cmd, Window wnd ){ XEvent event; event.xclient.type = ClientMessage; event.xclient.message_type = FORWARD_FOCUS; event.xclient.format = 32; event.xclient.data.l[0] = cmd; event.xclient.window = wnd; XSendEvent( X->dsp, wnd, False, StdEvents, &event);}static void retryFocus ( Window wnd, Window owner, int count ){ XEvent event; event.xclient.type = ClientMessage; event.xclient.message_type = RETRY_FOCUS; event.xclient.format = 32; event.xclient.data.l[0] = count; event.xclient.data.l[1] = owner; event.xclient.window = wnd; XSendEvent( X->dsp, wnd, False, StdEvents, &event); XSync( X->dsp, False);}static CursorgetCursor ( jint jCursor ){ Cursor cursor; if ( jCursor > 13 ) jCursor = 0; if ( !(cursor = X->cursors[jCursor]) ){ int shape; switch ( jCursor ) { case 0: shape = XC_top_left_arrow; break; /* 0: DEFAULT_CURSOR */ case 1: shape = XC_crosshair; break; /* 1: CROSSHAIR_CURSOR */ case 2: shape = XC_xterm; break; /* 2: TEXT_CURSOR */ case 3: shape = XC_watch; break; /* 3: WAIT_CURSOR */ case 4: shape = XC_bottom_left_corner; break; /* 4: SW_RESIZE_CURSOR */ case 5: shape = XC_bottom_right_corner; break; /* 5: SE_RESIZE_CURSOR */ case 6: shape = XC_top_left_corner; break; /* 6: NW_RESIZE_CURSOR */ case 7: shape = XC_top_right_corner; break; /* 7: NE_RESIZE_CURSOR */ case 8: shape = XC_top_side; break; /* 8: N_RESIZE_CURSOR */ case 9: shape = XC_bottom_side; break; /* 9: S_RESIZE_CURSOR */ case 10: shape = XC_left_side; break; /* 10: W_RESIZE_CURSOR */ case 11: shape = XC_right_side; break; /* 11: E_RESIZE_CURSOR */ case 12: shape = XC_hand2; break; /* 12: HAND_CURSOR */ case 13: shape = XC_fleur; break; /* 13: MOVE_CURSOR */ default: shape = XC_top_left_arrow; } cursor = X->cursors[jCursor] = XCreateFontCursor( X->dsp, shape); } return cursor;}voidJava_java_awt_Toolkit_wndSetTitle ( JNIEnv* env, jclass clazz UNUSED, jobject nwnd, jstring jTitle ){ Window wnd = UNVEIL_WND(nwnd); char *buf; if ( jTitle ) { buf = java2CString( env, X, jTitle); DBG( AWT_WND, printf("setTitle: %p, \"%s\"\n", wnd, buf)); XStoreName( X->dsp, wnd, buf); }}voidJava_java_awt_Toolkit_wndSetResizable ( JNIEnv* env UNUSED, jclass clazz UNUSED, jobject nwnd, jboolean isResizable, int x, int y, int width, int height ){ Window wnd = UNVEIL_WND(nwnd); XSizeHints hints; DBG( AWT_WND, printf("setResizable: %p, %d, %d,%d,%d,%d\n", wnd, isResizable, x,y,width,height)); if ( !isResizable ) { hints.min_width = hints.max_width = width; hints.min_height = hints.max_height = height; } else { hints.min_width = hints.min_height = 0; hints.max_width = hints.max_height = INT_MAX; } hints.flags = PMinSize | PMaxSize; XSetWMNormalHints( X->dsp, wnd, &hints);}static jobjectcreateWindow ( JNIEnv* env, jclass clazz, Window parent, Window owner, jstring jTitle, jint x, jint y, jint width, jint height, jint jCursor, jint clrBack, jboolean isResizable ){ unsigned long valueMask; XSetWindowAttributes attributes; Window wnd; Atom protocol[2]; int i; jobject nwnd; /* note that we don't select on key / focus events for popus (owner, no title) */ attributes.event_mask = (owner && !jTitle) ? PopupEvents : StdEvents; attributes.background_pixel = clrBack; attributes.bit_gravity = ForgetGravity; attributes.cursor = getCursor( jCursor); valueMask = CWEventMask | CWBackPixel | CWBitGravity | CWCursor; if ( !jTitle ) { attributes.override_redirect = True; attributes.save_under = True; valueMask |= CWOverrideRedirect | CWSaveUnder; } else { attributes.backing_store = WhenMapped; valueMask |= CWBackingStore; } if ( width <= 0 ) width = 1; if ( height <= 0 ) height = 1; DBG( AWT_WND, printf("XCreateWindow %d,%d,%d,%d\n", x, y, width, height)); wnd = XCreateWindow( X->dsp, parent, x, y, width, height, 0, CopyFromParent, InputOutput, CopyFromParent, valueMask, &attributes); DBG( AWT_WND, printf(" -> %lx\n", wnd)); if ( wnd ) { nwnd = JCL_NewRawDataObject(env, (void *)wnd); i=0; protocol[i++] = WM_DELETE_WINDOW; protocol[i++] = WM_TAKE_FOCUS; XSetWMProtocols( X->dsp, wnd, protocol, i); if ( owner ){ XSetTransientForHint( X->dsp, wnd, owner ); } if ( !isResizable ) Java_java_awt_Toolkit_wndSetResizable( env, clazz, nwnd, isResizable, x, y, width, height); if ( jTitle ) Java_java_awt_Toolkit_wndSetTitle( env, clazz, nwnd, jTitle); return nwnd; } else { return 0; }}/* * We register here (and not in evt.c, during evtRegisterSource) because * we want to be able to store attributes (flags, owner), without being * forced to use fancy intermediate cache mechanisms (or intermediate * register states). Storing own Window attributes (flags, owners) in the native * layer is essential for mechanisms like the popup focus forwarding, but can * be used in other places (like inset detection and mapping) as well, to avoid * costly round-trips or additional state passed in from the Java side */static intregisterSource ( Toolkit* tk, Window wnd, Window owner, int flags){ int i = getFreeSourceIdx( tk, wnd); if ( i >= 0 ) { tk->windows[i].w = wnd; tk->windows[i].flags = flags; tk->windows[i].owner = owner; return i; } else { DBG( AWT_EVT, printf("window table out of space: %d", tk->nWindows)); return -1; }}jobjectJava_java_awt_Toolkit_wndCreateFrame ( JNIEnv* env, jclass clazz, jstring jTitle, jint x, jint y, jint width, jint height, jint jCursor, jint clrBack, jboolean isResizable ){ jobject w = createWindow( env, clazz, DefaultRootWindow( X->dsp), 0, jTitle, x, y, width, height, jCursor, clrBack, isResizable); DBG( AWT_WND, printf("createFrame( %p, %d,%d,%d,%d,..) -> %lx\n", jTitle,x,y,width,height, w)); if ( w ) registerSource( X, UNVEIL_WND(w), 0, WND_FRAME); return w;}jobjectJava_java_awt_Toolkit_wndCreateWindow ( JNIEnv* env, jclass clazz, jobject nowner,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -