⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 evt.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * evt.c -  * * Copyright (c) 1998 *      Transvirtual Technologies, Inc.  All rights reserved. * * See the file "license.terms" for information on usage and redistribution  * of this file.  */#include "config.h"#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/keysym.h>#include "toolkit.h"#include "keysyms.h"#include "jcl.h"#if !defined (USE_POLLING_AWT)#include "jsyscall.h"#include "locks.h"#if defined(UNIX_JTHREADS)void jthreadedBlockEAGAIN(int fd);   /* move to SysCallInterface ? */int jthreadedFileDescriptor(int fd);#endif#endif /* !USE_POLLING_AWT *//******************************************************************************* * */static int nextEvent ( JNIEnv* env UNUSED, jclass clazz UNUSED, Toolkit *tk, int blockIt UNUSED ){  if ( tk->preFetched )	return 1;#if !defined(USE_POLLING_AWT) && !defined(SUN_AWT_FIX)  /*   * We can't use QueuedAfterFlush since it seems to rely on blocked IO. At least   * XFree86-3.3.2 subsequently hangs in _XFlushInt. This is the weak point of   * our multithreaded X support, which depends on the Xlib in use   */  if ( blockIt ) {                /* this is from a getNextEvent */	while ( tk->pending <= 0 ) {	  XFlush( tk->dsp);	  if ( (tk->pending = XEventsQueued( tk->dsp, QueuedAlready)) == 0 ) {		tk->blocking = 1;		/* Note that we might get blocked here, but we still have the Toolkit.class		 * lock. Since the new locking interface requires locks to occur symmetrical		 * inside of the same stack frame, we have to backup to some VM specific		 * functionality, here.		 */#if defined (UNIX_JTHREADS)		UNBLOCK_EXECUTE( clazz, (jthreadedBlockEAGAIN( ConnectionNumber( tk->dsp))));#elif defined (UNIX_PTHREADS)		/*		 * Even with pthreads, don't simply do a XNextEvent, because we most probably		 * would get "unexpected async replies" X errors when doing roundtrips (e.g.		 * direct or indirect XSyncs) from other threads while still being blocked in		 * XNextEvent, here. The only thing done outside the Toolkit lock should be		 * to check availability of X input		 */		{		  int stat;		  do {		    UNBLOCK_EXECUTE( clazz, (stat =select( ConnectionNumber(tk->dsp)+1, &tk->rfds, NULL,NULL,NULL)));		  }  while ( stat != 1 );		}#endif		/*		 * getting here just means we got input, it doesn't mean we have events. It also		 * doesn't mean there currently is no other thread doing X requests		 */		tk->blocking = 0;		tk->pending = XEventsQueued( tk->dsp, QueuedAfterReading);	  }	}  }  else {                         /* this is from a peekEvent */	if ( tk->blocking ){          /* nothing to expect, there is a pending getNextEvent */	  return 0;	}	if ( tk->pending <= 0 ) {	  XFlush( tk->dsp);	  if ( (tk->pending = XEventsQueued( tk->dsp, QueuedAlready)) == 0 ){		return 0;	  }	}  }#else /* USE_POLLING_AWT */  /*   * We need to use this one for Solaris.  We have problems trying to unblock the   * AWT thread off the X server connection.   */  if ( tk->pending <= 0 ) {	if ( (tk->pending = XEventsQueued( tk->dsp, QueuedAfterFlush)) == 0 )	  return 0;  }#endif /* !USE_POLLING_AWT */  XNextEvent( tk->dsp, &tk->event);  tk->pending--;  return 1;}/* X-to-Java key modifier mapping *                                     altGr   : PC *     shift       -    ctrl     alt    meta   : Java *     Shift    Lock    Ctrl    Mod1    Mod3   : X      symbol *  ---------------------------------------------------------- *         1       1       2       8       4   : Java   value *         1       2       4       8      32   : X */static inline int keyMod ( int keyState ){  int mod = 0;  if ( keyState & 3 ) mod |= 1; /* shift or lock */  if ( keyState & 4 ) mod |= 2;  if ( keyState & 8 ) mod |= 8;  return mod;}jclass     AWTEvent;jclass     ComponentEvent;jclass     MouseEvent;jclass     FocusEvent;jclass     WindowEvent;jclass     KeyEvent;jclass     PaintEvent;jclass     WMEvent;jmethodID  getComponentEvent;jmethodID  getMouseEvent;jmethodID  getFocusEvent;jmethodID  getWindowEvent;jmethodID  getKeyEvent;jmethodID  getPaintEvent;jmethodID  getWMEvent;#define    COMPONENT_RESIZED    101#define    WINDOW_CLOSING       201#define    WINDOW_CLOSED        202#define    WINDOW_ICONIFIED     203#define    WINDOW_DEICONIFIED   204#define    KEY_PRESSED          401#define    KEY_RELEASED         402#define    MOUSE_PRESSED        501#define    MOUSE_RELEASED       502#define    MOUSE_MOVED          503#define    MOUSE_ENTERED        504#define    MOUSE_EXITED         505#define    PAINT                800#define    UPDATE               801#define    FOCUS_GAINED        1004#define    FOCUS_LOST          1005#define    WM_KILLED           1905#if defined(KAFFE_VMDEBUG) && !defined(NDEBUG)static const char *eventStr ( int evtId ){  switch (evtId) {  case COMPONENT_RESIZED: return "ComponentResized";  case WINDOW_CLOSING: return "WindowClosing";  case WINDOW_CLOSED: return "WindowClosed";  case WINDOW_ICONIFIED: return "WindowIconified";  case WINDOW_DEICONIFIED: return "WindowDeiconified";  case KEY_PRESSED: return "KeyPressed";  case KEY_RELEASED: return "KeyReleased";  case MOUSE_PRESSED: return "MousePressed";  case MOUSE_RELEASED: return "MouseReleased";  case MOUSE_MOVED: return "MouseMoved";  case MOUSE_ENTERED: return "MouseEntered";  case MOUSE_EXITED: return "MouseExited";  case PAINT: return "Paint";  case UPDATE: return "Update";	  case FOCUS_GAINED: return "FocusGained";  case FOCUS_LOST: return "FocusLost";  case WM_KILLED: return "WMKilled";  default: return "<unknown>";  }};#endif /* defined(KAFFE_VMDEBUG) && !defined(NDEBUG) */static jobjectskip ( JNIEnv* env UNUSED, Toolkit* tk UNUSED ){  return NULL;}static jobjectkeyNotify ( JNIEnv* env, Toolkit* tk ){  KeySym          keysym;  KeySym          keysym2;  XComposeStatus  ioStatus;  int             n, keyCode, keyChar, mod, idx, nchar;  /*   * We should eventually support input methods here.   * Note that 'keysym' is queried separately (with a standard state), to   * ensure the "one physical key -> one keycode" invariant   */  n = XLookupString( &tk->event.xkey, tk->buf, tk->nBuf, &keysym2, &ioStatus);  keysym = XKeycodeToKeysym( tk->dsp, tk->event.xkey.keycode, 0);  /* Bug fix: the keypad numbers where not handled correctly.   * In X, numlock is a modifier, and XKeycodeToKeysym do   * not do any modifier interpretation (in order to   * build the correct Java KeyEvent).   * But, as a result, since there is no NumLock modifier   * in Java, the information was lost, and the keypad could   * not work with NumLock selected.   * The "solution" is to use the returned keysym from XLookupString   * (which interpret the modifiers) if and only if it    * the original keysym correspond to the keypad; this should   * code will all the case where the numlock alter the interpretation   * of the keypad; also, if the keysums are the xk_xp_<num>    * we set the keychar to the correspoding digit.   */  if ((keysym >= XK_KP_Space) && (keysym <= XK_KP_9)) {      keysym = keysym2;            switch (keysym)	{	case XK_KP_Multiply:	  nchar = '*';	  break;	case XK_KP_Add:	  nchar = '+';	  break;	case XK_KP_Separator:	  nchar = ',';	  break;	case XK_KP_Subtract:	  nchar = '-';	  break;	case XK_KP_Decimal:	  nchar = '.';	  break;	case XK_KP_Divide:	  nchar = '/';	  break;	case XK_KP_0:	  nchar = '0';	  break;	case XK_KP_1:	  nchar = '1';	  break;	case XK_KP_2:	  nchar = '2';	  break;	case XK_KP_3:	  nchar = '3';	  break;	case XK_KP_4:	  nchar = '4';	  break;	case XK_KP_5:	  nchar = '5';	  break;	case XK_KP_6:	  nchar = '6';	  break;	case XK_KP_7:	  nchar = '7';	  break;	case XK_KP_8:	  nchar = '8';	  break;	case XK_KP_9:	  nchar = '9';	  break;	default:	  nchar = -1;	  break;	}  }  else    nchar = -1;  if ( (keysym >= 0xff00) || (n == 0) ) {	keyCode = FKeyCode[keysym & 0xff];	/*	 * There are some "control keys" that should generate KEY_TYPED events	 * (enter, cancel, backspace, del, tab). This is flagged by a negative keyCode	 * value and leads to non-zero keyChars	 */	if ( keyCode < 0 ){	  keyChar = keyCode = -keyCode;	} else if (nchar >= 0) {	  keyChar = nchar;	}	else {  /* a "pure" function key */	  keyChar = 0;	}  }  else {	keyChar = (unsigned char)X->buf[0];	keyCode = LKeyCode[keysym & 0xff];  }  tk->evtId = (tk->event.xany.type == KeyPress)? KEY_PRESSED : KEY_RELEASED;  mod = keyMod( tk->event.xkey.state);  if ( tk->fwdIdx >= 0 ) {	/*	 * watch out - we still might have key events for a already	 * unregistered forwardee in the queue (since we fake X, we can't rely on it	 * to remove key events for a destroyed forwardee)	 */	if ( !checkSource( tk, tk->fwdIdx) )	  return 0;	idx = tk->fwdIdx;  }  else {	idx = tk->srcIdx;  }  return (*env)->CallStaticObjectMethod( env, KeyEvent, getKeyEvent,					 idx, tk->evtId, keyCode, keyChar, mod);}static jobjectbuttonNotify ( JNIEnv* env, Toolkit* tk ){  if ( tk->event.xany.type == ButtonPress ) {	tk->evtId = MOUSE_PRESSED;	if ( (tk->windows[tk->srcIdx].w == tk->focus) && (tk->fwdIdx >= 0) )	  forwardFocus( FWD_REVERT, tk->event.xany.window);  }  else {	tk->evtId = MOUSE_RELEASED;  }  return (*env)->CallStaticObjectMethod( env, MouseEvent, getMouseEvent,					 tk->srcIdx, tk->evtId,					 tk->event.xbutton.button,					 tk->event.xbutton.x, tk->event.xbutton.y);}static jobjectmotionNotify ( JNIEnv* env, Toolkit* tk ){  return (*env)->CallStaticObjectMethod( env, MouseEvent, getMouseEvent,					 tk->srcIdx, (tk->evtId = MOUSE_MOVED),					 0, tk->event.xmotion.x, tk->event.xmotion.y);}static jobjectmouseNotify ( JNIEnv* env, Toolkit* tk ){  tk->evtId = (tk->event.xany.type == EnterNotify) ? MOUSE_ENTERED : MOUSE_EXITED;  return (*env)->CallStaticObjectMethod( env, MouseEvent, getMouseEvent,					 tk->srcIdx, tk->evtId,					 0, tk->event.xcrossing.x, tk->event.xcrossing.y);}static jobjectfocusNotify ( JNIEnv* env, Toolkit* tk ){  int et = tk->event.xany.type;  int idx = (tk->focusFwd) ? tk->fwdIdx : tk->srcIdx;  /*   * get rid of all these fancy intermediate focus events (the real thing should   * come last), but be aware of that we might get events for already unregistered windows   * (in case the app isn't particulary careful with disposing windows), ending up in   * ArrayOutOfBoundsExceptions in the getFocusEvent   */  while ( XCheckMaskEvent( tk->dsp, FocusChangeMask, &tk->event) ){	tk->pending--;	if ( getSourceIdx( tk, tk->event.xfocus.window) >= 0 ) {	  et = tk->event.xany.type;	  idx = (tk->focusFwd) ? tk->fwdIdx : tk->srcIdx;	}  }  if ( et == FocusIn ) {	tk->evtId = FOCUS_GAINED;	tk->focus = tk->event.xany.window;  }  else {	tk->evtId = FOCUS_LOST;	tk->focus = 0;  }  /*   * No matter what the focus change is - if we get a REAL focus notification,   * it means that we will end focus forwarding (which is done on the owner-basis,   * not by means of a global grab mode)   */  resetFocusForwarding( tk);  if ( checkSource( tk, idx) ){	return (*env)->CallStaticObjectMethod( env, FocusEvent, getFocusEvent, idx,										   tk->evtId, JNI_FALSE);  }  else {	return 0;  }}static jobjectexpose ( JNIEnv* env, Toolkit* tk ){  Window  wnd = tk->event.xany.window;  int     x   = tk->event.xexpose.x;  int     y   = tk->event.xexpose.y;  int     w   = tk->event.xexpose.width;  int     h   = tk->event.xexpose.height;  int     xw, yh, exw, eyh;  while ( XCheckWindowEvent( tk->dsp, wnd, ExposureMask | StructureNotifyMask, &tk->event) ){	tk->pending--;	if ( tk->event.xany.type == Expose ) {	  xw = x + w;	  yh = y + h;	  exw = tk->event.xexpose.x + tk->event.xexpose.width;	  eyh = tk->event.xexpose.y + tk->event.xexpose.height;	  if ( tk->event.xexpose.x < x ) x = tk->event.xexpose.x;	  if ( tk->event.xexpose.y < y ) y = tk->event.xexpose.y;		  w = (exw > xw) ? exw - x : xw - x;	  h = (eyh > yh) ? eyh - y : yh - y;	}	else {	  tk->preFetched = 1;	  break;	}  }  return (*env)->CallStaticObjectMethod( env, PaintEvent, getPaintEvent,					 tk->srcIdx, (tk->evtId = UPDATE),					 x, y, w, h);}static jobject

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -