示例#1
0
void MessagePump::_initReceiverQueue()
{
    if( !_receiverQueue )
    {
        _receiverQueue = GetCurrentEventQueue();
        _needGlobalLock = ( _receiverQueue == GetMainEventQueue( ));
        EQASSERT( _receiverQueue );
    }

    EQASSERTINFO( _receiverQueue == GetCurrentEventQueue(),
                  "MessagePump::dispatch() called from two different threads" );
}
SkOSWindow::SkOSWindow(void* hWnd) : fHWND(hWnd)
{	
	static const EventTypeSpec  gTypes[] = {
		{ kEventClassKeyboard,  kEventRawKeyDown			},
        { kEventClassKeyboard,  kEventRawKeyUp              },
		{ kEventClassMouse,		kEventMouseDown				},
		{ kEventClassMouse,		kEventMouseDragged			},
		{ kEventClassMouse,		kEventMouseUp				},
		{ kEventClassTextInput, kEventTextInputUnicodeForKeyEvent   },
		{ kEventClassWindow,	kEventWindowBoundsChanged	},
		{ kEventClassWindow,	kEventWindowDrawContent		},
		{ SK_MacEventClass,		SK_MacEventKind				}
	};

	EventHandlerUPP handlerUPP = NewEventHandlerUPP(SkOSWindow::EventHandler);
	int				count = SK_ARRAY_COUNT(gTypes);
	OSStatus		result;

	result = InstallEventHandler(GetWindowEventTarget((WindowRef)hWnd), handlerUPP,
						count, gTypes, this, nil);
	SkASSERT(result == noErr);

	gCurrOSWin = this;
	gCurrEventQ = GetCurrentEventQueue();
	gEventTarget = GetWindowEventTarget((WindowRef)hWnd);

	static bool gOnce = true;
	if (gOnce) {
		gOnce = false;
		gPrevNewHandler = set_new_handler(sk_new_handler);
	}
}
示例#3
0
// ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
//		¥ CWaitMouseDownStatement::ExecuteSelf
// ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
void CWaitMouseDownStatement::ExecuteSelf(CProgram &inState)
{
	if (USE_RNE_FOR_SYNC_INPUT)
	{
		// if the mouse button is held when we enter, then we're done instantly
		if (Button())
			return;

		// otherwise, block our task until we get an event, if it's a mouse click, unblock, if not, handle it and reblock
		// this drops our cpu usage from 100 to pretty much zero on mac os x
		
		EventRef		e;

		// clear all pending mouse downs so we don't return immediately
		{
			EventTypeSpec	eventsList[]={ { kEventClassMouse, kEventMouseDown } };
			::FlushEventsMatchingListFromQueue(GetCurrentEventQueue(),1,eventsList);
		}
		
		// wait for a standard event with an infinite time out, this includes esc and cmd-. etc
		inState.TBReceiveNextEvent(EventListWithCount(CApplication::kStdEventsListPlusAllMouse),kEventDurationForever,false,&e);
		
		// if it's a mouse click, flush it and exit, if it's not a mouse click, don't flush it, let it be handled then repeat
		if ((::GetEventClass(e)==kEventClassMouse) && (::GetEventKind(e)==kEventMouseDown) && inState.MouseEventIsOverGameWindow(e))
		{
			// remove the event from the queue
			::RemoveEventFromQueue(GetCurrentEventQueue(),e);		// we now own e
			::ReleaseEvent(e);
		}
		else
		{
			ECHO("Non mouse up event, passing out and looping...");
			inState.SetPC(this);		// let the event out to our main handler and loop back into this command when it's done
		}
	}		
	else
	{
		if (!Button())
			inState.SetPC(this);
		else
		{
			#if TB_FlushEventsAllTheFeckinTime
			::FlushEvents(kUserInputEventMask,0L);
			#endif
		}
	}
}
示例#4
0
bool _init( const int argc, char** argv, NodeFactory* nodeFactory )
{
    const char *env = getenv( "EQ_LOG_LEVEL" );
    if( env )
        lunchbox::Log::level = lunchbox::Log::getLogLevel( env );

    env = getenv( "EQ_LOG_TOPICS" );
    if( env )
        lunchbox::Log::topics |= atoll( env );

    lunchbox::Log::instance().setThreadName( "Main" );

    if( ++_initialized > 1 ) // not first
    {
        LBINFO << "Equalizer client library initialized more than once"
               << std::endl;
        return true;
    }

    if( !_parseArguments( argc, argv ))
        return false;
    LBINFO << "Equalizer v" << Version::getString() << " initializing"
           << std::endl;

#ifdef AGL
    GetCurrentEventQueue();
#endif
#ifdef GLX
    ::XInitThreads();
#endif

#ifdef EQ_USE_PARACOMP
    LBINFO << "Initializing Paracomp library" << std::endl;
    PCerr err = pcSystemInitialize( 0 );
    if( err != PC_NO_ERROR )
    {
        LBERROR << "Paracomp initialization failed: " << err << std::endl;
        return false;
    }
#endif

    LBASSERT( nodeFactory );
    Global::_nodeFactory = nodeFactory;

    const std::string& programName = Global::getProgramName();
    if( programName.empty() && argc > 0 )
        Global::setProgramName( argv[0] );

    const std::string& workDir = Global::getWorkDir();
    if( workDir.empty( ))
    {
        char cwd[MAXPATHLEN];
        Global::setWorkDir( getcwd( cwd, MAXPATHLEN ));
    }

    _initPlugins();
    return fabric::init( argc, argv );
}
示例#5
0
// ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
//		¥ CWaitMouseUpStatement::ExecuteSelf
// ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
void CWaitMouseUpStatement::ExecuteSelf(CProgram &inState)
{
	if (USE_RNE_FOR_SYNC_INPUT)
	{
		if (!Button())		// mouse button ain't held, return instantly
			return;
			
		// otherwise, block until mouse up is received
		EventRef		e;

		// clear all pending mouse ups so we don't return immediately
		{
			EventTypeSpec	eventsList[]={ { kEventClassMouse, kEventMouseUp } };
			::FlushEventsMatchingListFromQueue(GetCurrentEventQueue(),1,eventsList);
		}

		// wait for a standard event with an infinite time out, this includes esc and cmd-. etc
		inState.TBReceiveNextEvent(EventListWithCount(CApplication::kStdEventsListPlusAllMouse),kEventDurationForever,false,&e);
		
		// if it's a mouse click, flush it and exit, if it's not a mouse click, don't flush it, let it be handled then repeat
		if ((::GetEventClass(e)==kEventClassMouse) && (::GetEventKind(e)==kEventMouseUp))
		{
			// remove the event from the queue
			::RemoveEventFromQueue(GetCurrentEventQueue(),e);		// we now own e
			::ReleaseEvent(e);
		}
		else
		{
			ECHO("Non mouse event, passing out and looping...");
			inState.SetForceEventProcess();		// get it processed and out of the q immediately
			inState.SetPC(this);		// let the event out to our main handler and loop back into this command when it's done
		}
	}
	else
	{
		if (Button())
			inState.SetPC(this);
		else
		{
			#if TB_FlushEventsAllTheFeckinTime
			::FlushEvents(kUserInputEventMask,0L);
			#endif
		}
	}
}
示例#6
0
bool _init( const int argc, char** argv, NodeFactory* nodeFactory )
{
    const char *env = getenv( "EQ_LOG_LEVEL" );
    if( env )
        lunchbox::Log::level = lunchbox::Log::getLogLevel( env );

    env = getenv( "EQ_LOG_TOPICS" );
    if( env )
        lunchbox::Log::topics |= atoll( env );

    lunchbox::Log::instance().setThreadName( "Main" );

    if( ++_initialized > 1 ) // not first
    {
        LBERROR << "Equalizer client library initialized more than once"
                << std::endl;
        return true;
    }

    if( !_parseArguments( argc, argv ))
        return false;
    LBDEBUG << "Equalizer v" << Version::getString() << " initializing"
            << std::endl;

#ifdef AGL
    GetCurrentEventQueue();
#endif
#ifdef GLX
    ::XInitThreads();
#endif

#ifdef EQUALIZER_USE_QT5WIDGETS
    if( QApplication::instance( ))
        _windowSystems.push_back( new qt::WindowSystem );
#endif

    LBASSERT( nodeFactory );
    Global::_nodeFactory = nodeFactory;

    const std::string& programName = Global::getProgramName();
    if( programName.empty() && argc > 0 )
        Global::setProgramName( argv[0] );

    const std::string& workDir = Global::getWorkDir();
    if( workDir.empty( ))
    {
        char cwd[MAXPATHLEN];
        Global::setWorkDir( getcwd( cwd, MAXPATHLEN ));
    }

    _initPlugins();
    return fabric::init( argc, argv );
}
示例#7
0
文件: init.cpp 项目: bohara/Equalizer
bool _init( const int argc, char** argv, NodeFactory* nodeFactory )
{
    const char *env = getenv( "EQ_LOG_LEVEL" );
    if( env )
        lunchbox::Log::level = lunchbox::Log::getLogLevel( env );

    env = getenv( "EQ_LOG_TOPICS" );
    if( env )
        lunchbox::Log::topics |= atoll( env );

    lunchbox::Log::instance().setThreadName( "Main" );
    _parseArguments( argc, argv );
    LBINFO << "Equalizer v" << Version::getString() << " initializing"
           << std::endl;

    if( ++_initialized > 1 ) // not first
    {
        LBINFO << "Equalizer client library initialized more than once"
               << std::endl;
        return true;
    }
//    _initErrors();

#ifdef AGL
    GetCurrentEventQueue();
#endif

#ifdef EQ_USE_PARACOMP
    LBINFO << "Initializing Paracomp library" << std::endl;
    PCerr err = pcSystemInitialize( 0 );
    if( err != PC_NO_ERROR )
    {
        LBERROR << "Paracomp initialization failed: " << err << std::endl;
        return false;
    }
#endif

    LBASSERT( nodeFactory );
    Global::_nodeFactory = nodeFactory;

    _initPlugins();
    return fabric::init( argc, argv );
}
示例#8
0
bool
QvisApplication::macEventFilter(EventHandlerCallRef er, EventRef event)
{
    UInt32 ekind = GetEventKind(event), eclass = GetEventClass(event);
    bool ret = false;

    switch(eclass)
    {
    case kEventClassWindow:
      { // new scope
        //qDebug("macEventFilter: kEventClassWindow");
        WindowRef wid;
        GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL,
                          sizeof(WindowRef), NULL, &wid);
        QWidget *widget = QWidget::find((WId)wid);
        if(widget)
        {
            if(ekind == kEventWindowShown)
            {
                QString mainWindowName(QString("VisIt ") + QString(VISIT_VERSION));
                if(mainWindowName == QString(widget->windowTitle()))
                    emit showApplication();
                //qDebug("ekind = kEventWindowShown");
            }
            else if(ekind == kEventWindowHidden)
            {
                QString mainWindowName(QString("VisIt ") + QString(VISIT_VERSION));
                if(mainWindowName == QString(widget->windowTitle()))
                    emit hideApplication();            
                //qDebug("ekind = kEventWindowHidden");
            }
#ifdef PRINT_CARBON_EVENTS
            else if(ekind == kEventWindowClose)
                qDebug("\tkEventWindowClose");
            else if(ekind == kEventWindowDrawContent)
                qDebug("\tkEventWindowDrawContent");
            else if(ekind == kEventWindowBoundsChanged)
                qDebug("\tkEventWindowBoundsChanged");
#endif
        }        
        break;
      }
    // Trap for other Carbon events.
    case kEventClassApplication:
        if(ekind == kEventAppDeactivated)
        {
            //qDebug("\tkEventAppDeactivated");

            // We're deactivating the application so the next time we activate it
            // via the menu, we need to make it active.
            needToMakeActive = true;
        }
        else if(ekind == kEventAppActivated)
        {
            //qDebug("\tkEventAppActivated");
            needToMakeActive = false;
        }
#ifdef PRINT_CARBON_EVENTS
        else if(ekind == kEventAppQuit)
            qDebug("\tkEventAppQuit");
        else if(ekind == kEventAppLaunchNotification)
            qDebug("\tkEventAppLaunchNotification");
        else if(ekind == kEventAppLaunched)
            qDebug("\tkEventAppLaunched");
        else if(ekind == kEventAppTerminated)
            qDebug("\tkEventAppTerminated");
        else if(ekind == kEventAppFrontSwitched)
            qDebug("\tkEventAppFrontSwitched");
        else if(ekind == kEventAppFocusMenuBar)
            qDebug("\tkEventAppFocusMenuBar");
        else if(ekind == kEventAppFocusNextDocumentWindow)
            qDebug("\tkEventAppFocusNextDocumentWindow");
        else if(ekind == kEventAppFocusNextFloatingWindow)
            qDebug("\tkEventAppFocusNextFloatingWindow");
        else if(ekind == kEventAppFocusToolbar)
            qDebug("\tkEventAppFocusToolbar");
        else if(ekind == kEventAppFocusDrawer)
            qDebug("\tkEventAppFocusDrawer");
        else if(ekind == kEventAppGetDockTileMenu)
            qDebug("\tkEventAppGetDockTileMenu");
        else if(ekind == kEventAppIsEventInInstantMouser)
            qDebug("\tkEventAppIsEventInInstantMouser");
        else if(ekind == kEventAppHidden)
            qDebug("\tkEventAppHidden");
        else if(ekind == kEventAppShown)
            qDebug("\tkEventAppShown");
        else if(ekind == kEventAppSystemUIModeChanged)
            qDebug("\tkEventAppSystemUIModeChanged");
        else if(ekind == kEventAppAvailableWindowBoundsChanged)
            qDebug("\tkEventAppAvailableWindowBoundsChanged");
        else if(ekind == kEventAppActiveWindowChanged)
            qDebug("\tkEventAppActiveWindowChanged");
        break;
    case kEventClassCommand:
        qDebug("kEventClassCommand");
        break;
    case kEventClassControl:
        qDebug("kEventClassControl");
        break;
    case kEventClassKeyboard:
        qDebug("kEventClassKeyboard");
        break;
#endif
    case kEventClassMenu:
#ifdef PRINT_CARBON_EVENTS
        qDebug("kEventClassMenu");
        if(ekind == kEventMenuBeginTracking)
            qDebug("\tkEventMenuBeginTracking");
        else if(ekind == kEventMenuEndTracking)
            qDebug("\tkEventMenuEndTracking");
        else if(ekind == kEventMenuChangeTrackingMode)
            qDebug("\tkEventMenuChangeTrackingMode");
        else if(ekind == kEventMenuClosed)
            qDebug("\tkEventMenuClosed");
        else if(ekind == kEventMenuTargetItem)
            qDebug("\tkEventMenuTargetItem");
        else if(ekind == kEventMenuMatchKey)
            qDebug("\tkEventMenuMatchKey");
        else if(ekind == kEventMenuEnableItems)
            qDebug("\tkEventMenuEnableItems");
        else
#endif
        if(ekind == kEventMenuOpening)
        {
            //qDebug("\tkEventMenuOpening");

            if(needToMakeActive)
            {
                // If we got here then it's from making the menu active after having
                // left the application for the viewer. In this case, we pull some 
                // tricks on Qt to make it execute the AppActivated event before the
                // current event.
                needToMakeActive = false;

                // Inject a Carbon event to make the application active.
                CreateEvent(NULL, kEventClassApplication, kEventAppActivated, GetCurrentEventTime(),
                     NULL, &request_make_app_active);
                PostEventToQueue(GetCurrentEventQueue(), request_make_app_active, kEventPriorityHigh);
                // Inject a directive to exit a sub-event loop that we'll be creating.
                QTimer::singleShot(10, this, SLOT(exitTheLoop()));

                // Start a new event loop to make the app active and then quit
                // the sub-event loop.
                eventLoop = new QEventLoop(0);
                eventLoop->exec();
            }
        }
        break;
#ifdef PRINT_CARBON_EVENTS
    case kEventClassMouse:
        qDebug("kEventClassMouse");
        break;
#endif
    }

    return ret;
}
示例#9
0
void
OSXEventQueueBuffer::init()
{
    m_carbonEventQueue = GetCurrentEventQueue();
}
示例#10
0
SkOSWindow::SkOSWindow(void* hWnd) : fHWND(hWnd), fAGLCtx(NULL)
{
	OSStatus    result;
    WindowRef   wr = (WindowRef)hWnd;

    HIViewRef imageView, parent;
    HIViewRef rootView = HIViewGetRoot(wr);
    HIViewFindByID(rootView, kHIViewWindowContentID, &parent);
    result = HIImageViewCreate(NULL, &imageView);
	SkASSERT(result == noErr);

    result = HIViewAddSubview(parent, imageView);
	SkASSERT(result == noErr);

    fHVIEW = imageView;

    HIViewSetVisible(imageView, true);
    HIViewPlaceInSuperviewAt(imageView, 0, 0);

    if (true) {
        HILayoutInfo layout;
        layout.version = kHILayoutInfoVersionZero;
        set_bindingside(&layout.binding.left, parent, kHILayoutBindLeft);
        set_bindingside(&layout.binding.top, parent, kHILayoutBindTop);
        set_bindingside(&layout.binding.right, parent, kHILayoutBindRight);
        set_bindingside(&layout.binding.bottom, parent, kHILayoutBindBottom);
        set_axisscale(&layout.scale.x, parent);
        set_axisscale(&layout.scale.y, parent);
        set_axisposition(&layout.position.x, parent, kHILayoutPositionLeft);
        set_axisposition(&layout.position.y, rootView, kHILayoutPositionTop);
        HIViewSetLayoutInfo(imageView, &layout);
    }

    HIImageViewSetOpaque(imageView, true);
    HIImageViewSetScaleToFit(imageView, false);

	static const EventTypeSpec  gTypes[] = {
		{ kEventClassKeyboard,  kEventRawKeyDown			},
        { kEventClassKeyboard,  kEventRawKeyUp              },
		{ kEventClassMouse,		kEventMouseDown				},
		{ kEventClassMouse,		kEventMouseDragged			},
		{ kEventClassMouse,		kEventMouseMoved			},
		{ kEventClassMouse,		kEventMouseUp				},
		{ kEventClassTextInput, kEventTextInputUnicodeForKeyEvent   },
		{ kEventClassWindow,	kEventWindowBoundsChanged	},
//		{ kEventClassWindow,	kEventWindowDrawContent		},
		{ SK_MacEventClass,		SK_MacEventKind				}
	};

	EventHandlerUPP handlerUPP = NewEventHandlerUPP(SkOSWindow::EventHandler);
	int				count = SK_ARRAY_COUNT(gTypes);

	result = InstallEventHandler(GetWindowEventTarget(wr), handlerUPP,
						count, gTypes, this, nil);
	SkASSERT(result == noErr);

	gCurrOSWin = this;
	gCurrEventQ = GetCurrentEventQueue();
	gEventTarget = GetWindowEventTarget(wr);

	static bool gOnce = true;
	if (gOnce) {
		gOnce = false;
		gPrevNewHandler = set_new_handler(sk_new_handler);
	}
}
示例#11
0
static pascal OSStatus ControllerEventHandler (EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
	OSStatus	err, result = eventNotHandledErr;
	WindowRef	tWindowRef;

	tWindowRef = (WindowRef) inUserData;

	switch (GetEventClass(inEvent))
	{
		case kEventClassWindow:
			switch (GetEventKind(inEvent))
			{
				case kEventWindowClose:
					QuitAppModalLoopForWindow(tWindowRef);
					result = noErr;
					break;
			}

			break;

		case kEventClassCommand:
			switch (GetEventKind(inEvent))
			{
				HICommand	tHICommand;

				case kEventCommandUpdateStatus:
					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
					if (err == noErr && tHICommand.commandID == 'clos')
					{
						UpdateMenuCommandStatus(true);
						result = noErr;
					}

					break;

				case kEventCommandProcess:
					err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
					if (err == noErr)
					{
						if (tHICommand.commandID == 'CLRa')
						{
							ClearPadSetting();
							result = noErr;
						}
						else
						{
							SInt32	command = -1, count;

							for (count = 0; count < kNeedCount; count++)
								if (tHICommand.commandID == gControlIDs[count].signature)
									command = count;

							if (command >= 0)
							{
								pRecDevice	pDevice;
								pRecElement	pElement;

								FlushEventQueue(GetCurrentEventQueue());

								if (HIDConfigureAction(&pDevice, &pElement, 2.5f))
								{
									if (command < MAC_MAX_PLAYERS * 4)	// Direction
									{
										int		i    = command >> 2;	// Player
										long	curv = HIDGetElementValue(pDevice, pElement);

										if (pElement->usage == kHIDUsage_GD_Hatswitch)	// Hat Switch
										{
											gActionRecs[kUp(i)].fDevice  = gActionRecs[kDn(i)].fDevice  = gActionRecs[kLf(i)].fDevice  = gActionRecs[kRt(i)].fDevice  = pDevice;
											gActionRecs[kUp(i)].fElement = gActionRecs[kDn(i)].fElement = gActionRecs[kLf(i)].fElement = gActionRecs[kRt(i)].fElement = pElement;

											if (pDevice->vendorID == 1103)	// Thrustmaster
												gDirectionInfo[i].type = (pElement->max > 4) ? kPadElemTypeOtherHat8 : kPadElemTypeOtherHat4;
											else
											{
												if (pElement->max > 4)
												{
													if (((command % 4 == 0) && (curv == 0)) ||	// Up    : 0
														((command % 4 == 1) && (curv == 4)) ||	// Down  : 4
														((command % 4 == 2) && (curv == 6)) ||	// Left  : 6
														((command % 4 == 3) && (curv == 2)))	// Right : 2
														gDirectionInfo[i].type = kPadElemTypeOtherHat8;
													else
														gDirectionInfo[i].type = kPadElemTypeHat8;
												}
												else
												{
													if (((command % 4 == 0) && (curv == 0)) ||	// Up    : 0
														((command % 4 == 1) && (curv == 2)) ||	// Down  : 2
														((command % 4 == 2) && (curv == 3)) ||	// Left  : 3
														((command % 4 == 3) && (curv == 1)))	// Right : 1
														gDirectionInfo[i].type = kPadElemTypeOtherHat4;
													else
														gDirectionInfo[i].type = kPadElemTypeHat4;
												}
											}

											gDirectionInfo[i].device [kPadHat] = pDevice;
											gDirectionInfo[i].element[kPadHat] = pElement;
											gDirectionInfo[i].max    [kPadHat] = pElement->max;
											gDirectionInfo[i].min    [kPadHat] = pElement->min;
										}
										else
										if (pElement->max - pElement->min > 1)			// Axis (maybe)
										{
											if ((command % 4 == 0) || (command % 4 == 1))	// Up or Dn
											{
												gActionRecs[kUp(i)].fDevice  = gActionRecs[kDn(i)].fDevice  = pDevice;
												gActionRecs[kUp(i)].fElement = gActionRecs[kDn(i)].fElement = pElement;

												gDirectionInfo[i].type               = kPadElemTypeAxis;
												gDirectionInfo[i].device [kPadYAxis] = pDevice;
												gDirectionInfo[i].element[kPadYAxis] = pElement;
												gDirectionInfo[i].max    [kPadYAxis] = pElement->max;
												gDirectionInfo[i].min    [kPadYAxis] = pElement->min;
												gDirectionInfo[i].mid    [kPadYAxis] = (gDirectionInfo[i].max[kPadYAxis] + gDirectionInfo[i].min[kPadYAxis]) >> 1;
												gDirectionInfo[i].maxmid [kPadYAxis] = (gDirectionInfo[i].max[kPadYAxis] + gDirectionInfo[i].mid[kPadYAxis]) >> 1;
												gDirectionInfo[i].midmin [kPadYAxis] = (gDirectionInfo[i].mid[kPadYAxis] + gDirectionInfo[i].min[kPadYAxis]) >> 1;
											}
											else											// Lf or Rt
											{
												gActionRecs[kLf(i)].fDevice  = gActionRecs[kRt(i)].fDevice  = pDevice;
												gActionRecs[kLf(i)].fElement = gActionRecs[kRt(i)].fElement = pElement;

												gDirectionInfo[i].type               = kPadElemTypeAxis;
												gDirectionInfo[i].device [kPadXAxis] = pDevice;
												gDirectionInfo[i].element[kPadXAxis] = pElement;
												gDirectionInfo[i].max    [kPadXAxis] = pElement->max;
												gDirectionInfo[i].min    [kPadXAxis] = pElement->min;
												gDirectionInfo[i].mid    [kPadXAxis] = (gDirectionInfo[i].max[kPadXAxis] + gDirectionInfo[i].min[kPadXAxis]) >> 1;
												gDirectionInfo[i].maxmid [kPadXAxis] = (gDirectionInfo[i].max[kPadXAxis] + gDirectionInfo[i].mid[kPadXAxis]) >> 1;
												gDirectionInfo[i].midmin [kPadXAxis] = (gDirectionInfo[i].mid[kPadXAxis] + gDirectionInfo[i].min[kPadXAxis]) >> 1;
											}
										}
										else											// Button (maybe)
										{
											gActionRecs[command].fDevice  = pDevice;
											gActionRecs[command].fElement = pElement;
											gDirectionInfo[i].type = kPadElemTypeButton;
										}

										gDirectionHint[i] = gDirectionInfo[i].type;
									}
									else
									{
										gActionRecs[command].fDevice  = pDevice;
										gActionRecs[command].fElement = pElement;
									}
								}