x11uitoolkit.cpp
来自「这是VCF框架的代码」· C++ 代码 · 共 2,479 行 · 第 1/4 页
CPP
2,479 行
} while ( xPending() ); if ( quitMessageReceived ) { while ( xPending() ) { XNextEvent( x11Display_, &x11event ); } printf( "quitMessageReceived! leaving the X11UIToolkit::runEventLoop()!\n" ); return; } handlePaintEvents(); //check timers timersAvailable( availableTimers ); if ( !availableTimers.empty() ) { fireTimers( availableTimers ); } //reset the idle flag idleTime = true; }}UIToolkit::ModalReturnType X11UIToolkit::runModalEventLoopFor( Control* control ){ UIToolkit::ModalReturnType result = UIToolkit::mrFalse; printf( "starting X11UIToolkit runModalEventLoopFor( %p )...\n", control ); std::vector<TimerEntry> availableTimers; Application* runningApp = Application::getRunningInstance(); //initial outer loop - this will have idle time processing if possible bool idleTime = true; while ( true ) { //quit if we get a Ctrl+C from the console if ( consoleQuitHandlerCalled_ ) { return result; } XFlush(x11Display_); //check timers timersAvailable( availableTimers ); if ( !availableTimers.empty() ) { fireTimers( availableTimers ); } //phase 1 of event inner loop - idle processing while ( (!xPending() ) && (true == idleTime) ) { if ( NULL != runningApp ) { runningApp->idleTime(); } //check library apps; Enumerator<LibraryApplication*>* registeredLibs = LibraryApplication::getRegisteredLibraries(); while ( true == registeredLibs->hasMoreElements() ) { LibraryApplication* libraryApp = registeredLibs->nextElement(); libraryApp->idleTime(); } //only allow one cycle for now... idleTime = false; } //sleep just a bit System::sleep(1); XEvent x11event; Rect updateRect; /** phase 2 of inner event loop this phase will capture XEvents and pass them along to the various registered control peers. */ bool quitMessageReceived = false; do { if ( consoleQuitHandlerCalled_ ) { return result; } //handle toolkit messages if ( !handleToolkitMessages() ) { //oops looks like we got a quit message quitMessageReceived = true; printf( "quitMessageReceived = true, handleToolkitMessages() returned false\n" ); XFlush(x11Display_); break; } /** Why is this here? We do a quick check to see if there are truly any events in the queue - if there are not tehn we do NOT want to call XNextEvent, which will BLOCK till there are events in the queue. By placing this here, we ensure that we will complete a cycle of the loop and not cause it to hang here waiting for events */ if ( xPending() ) { XNextEvent( x11Display_, &x11event ); bool doTranslateAndDispatch = true; switch ( x11event.type ) { case KeyPress : { AbstractX11Control* xwndControl = AbstractX11Control::getX11ControlFromXWindow( x11event.xkey.window ); Control* control = NULL; if ( NULL != xwndControl ) { control = xwndControl->getControl(); Control* currentFocusedControl = Control::getCurrentFocusedControl(); if ( NULL != currentFocusedControl ) { if ( (control != currentFocusedControl) && (currentFocusedControl->isLightWeight()) ) { control = currentFocusedControl; } } } X11EventMsg eventMsg( &x11event, control ); VCF::Event* event = createEventFromNativeOSEventData( (void*)&eventMsg ); if ( NULL != event ) { //handle tabbing here handleKeyboardEvent( reinterpret_cast<KeyboardEvent*>( event ) ); if ( event->isConsumed() ) { doTranslateAndDispatch = false; } } delete event; } break; case KeyRelease : { XKeyEvent xkey = x11event.xkey; int keyCode = xkey.keycode; KeySym keySym; memset(&keySym, 0, sizeof(KeySym) ); char keyBuffer[X_KEYBUFFER_SIZE]; memset( keyBuffer, 0, sizeof(keyBuffer) ); int count = XLookupString( &xkey, keyBuffer, X_KEYBUFFER_SIZE-1, &keySym, 0 ); VirtualKeyCode code = translateKeyCode( keySym ); if ( code == vkEscape ) { quitMessageReceived = true; XFlush(x11Display_); break; } } break; case Expose: case GraphicsExpose: { updateRect.setRect( x11event.xexpose.x, x11event.xexpose.y, x11event.xexpose.x + x11event.xexpose.width, x11event.xexpose.y + x11event.xexpose.height ); //adds a new update rect to the list AbstractX11Control* xwndControl = AbstractX11Control::getX11ControlFromXWindow( x11event.xexpose.window ); if ( NULL != xwndControl ) { xwndControl->addUpdateRect( updateRect ); paintEventQueue_[xwndControl] = xwndControl; } //don't dispatch the xevent - we'll handle this as a special case doTranslateAndDispatch = false; } break; default : { //need to figure out what a quit message is } break; } /** if we have some to deal with lets do so here */ if ( doTranslateAndDispatch ) { AbstractX11Control::handleXEvent( x11event.xany.window, &x11event ); } } //check timers timersAvailable( availableTimers ); if ( !availableTimers.empty() ) { fireTimers( availableTimers ); } } while ( xPending() ); if ( quitMessageReceived ) { while ( xPending() ) { XNextEvent( x11Display_, &x11event ); } printf( "quitMessageReceived! leaving the X11UIToolkit::runModalEventLoopFor()!\n" ); return result; } handlePaintEvents(); //check timers timersAvailable( availableTimers ); if ( !availableTimers.empty() ) { fireTimers( availableTimers ); } //reset the idle flag idleTime = true; } return result;}/***@param void* in this implementation, the eventData represents a*pointer to an X11 XEvent structure.*/VCF::Event* X11UIToolkit::createEventFromNativeOSEventData( void* eventData ){ X11EventMsg* eventMsg = (X11EventMsg*)eventData; XEvent* x11Event = eventMsg->x11event_; VCF::Event* result = NULL; switch ( x11Event->type ) { case KeyRelease : case KeyPress : { XKeyEvent xkey = x11Event->xkey; //note - the Qt folks generously note that HPUX seems to have //a clusterfuck in their implementation - should we ever have the misfortune to //run on these systems we may have to fix things witrh state int keyCode = xkey.keycode; KeySym keySym; memset(&keySym, 0, sizeof(KeySym) ); char keyBuffer[X_KEYBUFFER_SIZE]; memset( keyBuffer, 0, sizeof(keyBuffer) ); int count = XLookupString( &xkey, keyBuffer, X_KEYBUFFER_SIZE-1, &keySym, 0 ); ulong32 eventType = (x11Event->type == KeyPress) ? Control::KEYBOARD_DOWN : Control::KEYBOARD_UP; result = new VCF::KeyboardEvent( eventMsg->control_, eventType, 1, translateKeyMask(xkey.state), keyBuffer[0], translateKeyCode( keySym ) ); } break; case ButtonPress : case ButtonRelease : { VCF::Point pt( x11Event->xbutton.x, x11Event->xbutton.y ); ulong32 eventType = (x11Event->type == ButtonPress) ? Control::MOUSE_DOWN : Control::MOUSE_UP; result = new VCF::MouseEvent ( eventMsg->control_, eventType, translateButtonMask( x11Event->xbutton.button ), translateKeyMask( x11Event->xbutton.state ), &pt ); } break; case MotionNotify : { VCF::Point pt( x11Event->xmotion.x, x11Event->xmotion.y ); result = new VCF::MouseEvent ( eventMsg->control_, Control::MOUSE_MOVE, translateButtonMask( x11Event->xmotion.state ), translateKeyMask( x11Event->xmotion.state ), &pt ); } break; case LeaveNotify : case EnterNotify : { VCF::Point pt( x11Event->xcrossing.x, x11Event->xcrossing.y ); ulong32 eventType = (x11Event->type == EnterNotify) ? Control::MOUSE_ENTERED : Control::MOUSE_LEAVE; //the peer will fill out the button and key masks result = new VCF::MouseEvent ( eventMsg->control_, eventType, 0, 0, &pt ); } break; case FocusIn : { result = new VCF::FocusEvent ( eventMsg->control_, Control::FOCUS_GAINED ); } break; case FocusOut : { result = new VCF::FocusEvent ( eventMsg->control_, Control::FOCUS_LOST ); } break; case NoExpose : { } break; case CreateNotify : { } break; case DestroyNotify : { result = new VCF::ComponentEvent( eventMsg->control_, Component::COMPONENT_DELETED ); } break; case UnmapNotify : { } break; case MapNotify : { } break; case MapRequest : { } break; case ReparentNotify : { } break; case ConfigureNotify : { //we are going to return NULL here - //the problem is that there are two separate VCF event objects that //need to be created, so we are going to let teh AbstractX11Control deal //with this directly } break; case GravityNotify : { } break; case ResizeRequest : { } break; case ConfigureRequest : { } break; case CirculateNotify : { } break; case CirculateRequest : { } break; case PropertyNotify : { } break; case SelectionClear : { } break; case SelectionRequest : { } break; case SelectionNotify : { } break; case ColormapNotify : { } break; case ClientMessage : { } break; case MappingNotify : { } break; case KeymapNotify : { } break; } return result;}Size X11UIToolkit::getDragDropDelta(){ //this is completely arbitrary - need to read this from a file Size result(4,4); return result;}String X11UIToolkit::getX11ErrorMessage( XID id ){ String result; return result;}void X11UIToolkit::createDefaultParentWnd(){ X11GraphicsToolkit* toolkit = (X11GraphicsToolkit*)GraphicsToolkit::getDefaultGraphicsToolkit(); XSetWindowAttributes attrs; memset( &attrs, 0, sizeof(XSetWindowAttributes) ); attrs.background_pixmap = None; attrs.background_pixel = 0; attrs.border_pixmap = CopyFromParent; attrs.border_pixel = 0; attrs.bit_gravity = ForgetGravity; attrs.win_gravity = NorthWestGravity; attrs.backing_store = NotUseful; attrs.colormap = CopyFromParent; attrs.backing_planes = 0xffffffff; attrs.cursor = None; defaultParentWnd_ = XCreateWindow( x11Display_, DefaultRootWindow( x11Display_ ), 0, 0, 1, 1, 0, CopyFromParent,//DefaultDepth( x11Display_, toolkit->getX11ScreenID() ), InputOutput, CopyFromParent,//DefaultVisual( x11Display_, toolkit->getX11ScreenID() ), 1, &attrs ); if ( NULL != defaultParentWnd_ ) { //XMapWindow( x11Display_, defaultParentWnd_ ); } else { throw InvalidPointerException( MAKE_ERROR_MSG_2("XCreateWindow returned a NULL window ID in creating the default parent wnd") ); }}void X11UIToolkit::consoleQuitHandler( int sig ){ signal(sig, SIG_IGN); X11UIToolkit* toolkit = (X11UIToolkit*) UIToolkit::getDefaultUIToolkit(); toolkit->consoleQuitHandlerCalled_ = true;}VirtualKeyCode X11UIToolkit::translateKeyCode( KeySym code ){ VirtualKeyCode result; /** please note: all codes from X11/keysymdef.h */ switch ( code ) { case XK_F1 :{ result = VCF::vkF1; } break; case XK_F2 :{ result = VCF::vkF2; } break; case XK_F3 :{ result = VCF::vkF3; } break; case XK_F4 :{ result = VCF::vkF4; } break; case XK_F5 :{ result = VCF::vkF5; } break; case XK_F6 :{ result = VCF::vkF6; } break; case XK_F7 :{ result = VCF::vkF7; } break; case XK_F8 :{ result = VCF::vkF8; } break; case XK_F9 :{ result = VCF::vkF9; } break; case XK_F10 :{ result = VCF::vkF10; } break; case XK_F11 :{ result = VCF::vkF11; } break; case XK_F12 :{ result = VCF::vkF12; } break; case XK_KP_Up : case XK_Up :{ result = VCF::vkUpArrow; } break; case XK_KP_Down : case XK_Down :{ result = VCF::vkDownArrow; } break; case XK_KP_Left : case XK_Left :{ result = VCF::vkLeftArrow; } break; case XK_KP_Right : case XK_Right :{ result = VCF::vkRightArrow; } break; case XK_Delete :{ result = VCF::vkDelete; } break; case XK_Return :{ result = VCF::vkReturn; } break; case XK_BackSpace :{ result = VCF::vkBackSpace; } break; case XK_space :{ result = VCF::vkSpaceBar; } break; case XK_Escape :{ result = VCF::vkEscape; } break; case XK_Page_Down :{ result = VCF::vkPgDown; } break; case XK_Page_Up :{ result = VCF::vkPgUp; } break; case XK_Home :{ result = VCF::vkHome; } break; case XK_End :{ result = VCF::vkEnd; } break; case XK_Control_R : case XK_Control_L :{ result = VCF::vkCtrl; } break; case XK_Alt_R : case XK_Alt_L :{ result = VCF::vkAlt; } break; case XK_Shift_R : case XK_Shift_L :{ result = VCF::vkShift;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?