(crash) Eventhandler and Lion

Mac OSX specific forum
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

(crash) Eventhandler and Lion

Post by jesperbrannmark »

Hi all.
I said before I had some crashes from my users who uses Lion. I have now updated myself and see where the problem is:
For you that has Lion, try this and maybe someone knows whats its all about.... Just do a mouseclick or a mousewheel or whatever event... I get IMA on the eventhandler procedure.

http://www.purebasic.fr/english/viewtop ... 90#p352890

(the code copy pasted here from the original post)

Code: Select all

EnableExplicit

ImportC ""
  GetEventClass(Event)
EndImport

; Event Class Constants

#kEventClassMouse = 'mous'
#kEventClassKeyboard = 'keyb'

; Event Modifier Constants

#cmdKeyBit = 8
#shiftKeyBit = 9
#alphaLockBit = 10
#optionKeyBit = 11
#controlKeyBit = 12

; Event Modifier Bits

#cmdKey = 1 << #cmdKeyBit
#shiftKey = 1 << #shiftKeyBit
#alphaLock = 1 << #alphaLockBit
#optionKey = 1 << #optionKeyBit
#controlKey = 1 << #controlKeyBit

; Character Codes

#kHomeCharCode = 1
#kEnterCharCode = 3
#kEndCharCode = 4
#kBackspaceCharCode = 8
#kTabCharCode = 9
#kPageUpCharCode = 11
#kPageDownCharCode = 12
#kReturnCharCode = 13
#kFunctionKeyCharCode = 16
#kEscapeCharCode = 27
#kLeftArrowCharCode = 28
#kRightArrowCharCode = 29
#kUpArrowCharCode = 30
#kDownArrowCharCode = 31
#kSpaceCharCode = 32
#kDeleteCharCode = 127

; Keyboard Event Constants

#kEventRawKeyDown = 1
#kEventRawKeyUp = 3
#kEventRawKeyModifiersChanged = 4

; Keyboard Event Parameters and Types

#kEventParamKeyCode = 'kcod'
#kEventParamKeyMacCharCodes = 'kchr'
#kEventParamKeyModifiers = 'kmod'

; Mouse Events

#kEventMouseDown = 1
#kEventMouseUp = 2
#kEventMouseWheelMoved = 10

; Mouse Button Constants

#kEventMouseButtonPrimary = 1
#kEventMouseButtonSecondary = 2
#kEventMouseButtonTertiary = 3

; Mouse Wheel Constants

#kEventMouseWheelAxisX = 0
#kEventMouseWheelAxisY = 1

; Mouse Event Parameters

#kEventParamMouseButton = 'mbtn'
#kEventParamMouseWheelAxis = 'mwax'
#kEventParamMouseWheelDelta = 'mwdl'
#typeMouseButton = 'mbtn'
#typeMouseWheelAxis = 'mwax'

; Mouse Tracking Constants

#kMouseTrackingMouseDown = 1
#kMouseTrackingMouseUp = 2

; Types

#typeChar = 'TEXT'
#typeSInt32 = 'long'
#typeUInt32 = 'magn'

Structure EventTypeSpec
  EventClass.L
  EventKind.L
EndStructure

Define EventHandlerUPP.L
Define i.L

Dim FnKey.L(18)

For i = 0 To 18
  Read.L FnKey(i)
Next i 

Procedure EventHandler(*NextEventHandler, Event.L, UserData.L)
  Shared FnKey.L()

  Protected i.L
  Protected KeyCode.L
  Protected KeyModifier.L
  Protected KeyModifierList.S
  Protected KeyName.S
  Protected MouseButtonType.L
  Protected MouseWheelAxis.L
  Protected MouseWheelDelta.L
  Protected WheelInfo.S

  Select GetEventClass(Event)
    Case #kEventClassMouse
      Select GetEventKind_(Event)
        Case #kEventMouseDown
          If GetEventParameter_(Event, #kEventParamMouseButton, #typeMouseButton, 0, SizeOf(MouseButtonType), 0, @MouseButtonType) = 0
            If GetEventParameter_(Event, #kEventParamKeyModifiers, #typeUInt32, 0, SizeOf(KeyModifier), 0, @KeyModifier) = 0
              Select MouseButtonType
                Case #kEventMouseButtonPrimary
                  If KeyModifier = #controlKey
                    SetGadgetText(1, "Right mouse button")
                  Else
                    SetGadgetText(1, "Left mouse button")
                  EndIf
                Case #kEventMouseButtonSecondary
                  SetGadgetText(1, "Right mouse button")
                Case #kEventMouseButtonTertiary
                  SetGadgetText(1, "Middle mouse button")
              EndSelect
            EndIf
          EndIf
        Case #kEventMouseUp
          SetGadgetText(1, "")
        Case #kEventMouseWheelMoved
          If GetEventParameter_(Event, #kEventParamMouseWheelAxis, #typeMouseWheelAxis, 0, SizeOf(MouseWheelAxis), 0, @MouseWheelAxis) = 0
            Select MouseWheelAxis
              Case #kEventMouseWheelAxisX
                WheelInfo = "Mouse wheel moved horizontally"
              Case #kEventMouseWheelAxisY
                WheelInfo = "Mouse wheel moved vertically"
            EndSelect
          EndIf

          If GetEventParameter_(Event, #kEventParamMouseWheelDelta, #typeSInt32, 0, 4, 0, @MouseWheelDelta) = 0
            WheelInfo + ", Delta = " + Str(MouseWheelDelta)
            SetGadgetText(1, WheelInfo)
          EndIf
      EndSelect
    Case #kEventClassKeyboard
      Select GetEventKind_(Event)
        Case #kEventRawKeyDown
          GetEventParameter_(Event, #kEventParamKeyMacCharCodes, #typeChar, 0, SizeOf(KeyCode), 0, @KeyCode)

          Select KeyCode
            Case #kBackspaceCharCode
              KeyName = "Backspace"
            Case #kDeleteCharCode
              KeyName = "Delete"
            Case #kEndCharCode
              KeyName = "End"
            Case #kEnterCharCode
              KeyName = "Enter"
            Case #kEscapeCharCode
              KeyName = "Esc"
            Case #kFunctionKeyCharCode
              If GetEventParameter_(Event, #kEventParamKeyCode, #typeUInt32, 0, SizeOf(KeyModifier), 0, @KeyCode) = 0
                For i = 0 To 18
                  If KeyCode = FnKey(i)
                    KeyName = "F" + Str(i + 1)
                    Break
                  EndIf
                Next i
              EndIf
            Case #kHomeCharCode
              KeyName = "Home"
            Case #kReturnCharCode
              KeyName = "Return"
            Case #kPageDownCharCode
              KeyName = "PageDown"
            Case #kPageUpCharCode
              KeyName = "PageUp"
            Case #kSpaceCharCode
              KeyName = "Space"
            Case #kTabCharCode
              KeyName = "Tab"
            Case #kUpArrowCharCode
              KeyName = "UpArrow"
            Case #kDownArrowCharCode
              KeyName = "DownArrow"
            Case #kLeftArrowCharCode
              KeyName = "LeftArrow"
            Case #kRightArrowCharCode
              KeyName = "RightArrow"
            Default
              KeyName = LCase(Chr(KeyCode))
          EndSelect
        Case #kEventRawKeyUp
          KeyName = ""
      EndSelect

      If GetEventParameter_(Event, #kEventParamKeyModifiers, #typeUInt32, 0, SizeOf(KeyModifier), 0, @KeyModifier) = 0
        If KeyModifier & #cmdKey
          KeyModifierList + "<Cmd> "
        EndIf
        
        If KeyModifier & #shiftKey
          KeyModifierList + "<Shift> "
        EndIf
        
        If KeyModifier & #alphaLock
          KeyModifierList + "<AlphaLock> "
        EndIf
        
        If KeyModifier & #optionKey
          KeyModifierList + "<Alt> "
        EndIf
        
        If KeyModifier & #controlKey
          KeyModifierList + "<Ctrl> "
        EndIf
      EndIf

      If KeyCode
        SetGadgetText(1, KeyModifierList + "<" + KeyName + ">")
      Else
        SetGadgetText(1, KeyModifierList)
      EndIf
  EndSelect

  If *NextEventHandler
    CallNextEventHandler_(*NextEventHandler, Event)
  EndIf
EndProcedure

Dim EventTypes.EventTypeSpec(5)

OpenWindow(0, 200, 100, 420, 70, "Detect mouse button, wheel, key and modifier events")
TextGadget(0, 10, 10, WindowWidth(0) - 20, 20, "Press and hold mouse button or key:", #PB_Text_Center)
TextGadget(1, 10, 35, WindowWidth(0) - 20, 20, "", #PB_Text_Border | #PB_Text_Center)

; ----- Install EventHandler

EventHandlerUPP = NewEventHandlerUPP_(@EventHandler())

; ----- Intercept mouse button down and up events

EventTypes(0)\EventClass = #kEventClassMouse
EventTypes(0)\EventKind  = #kEventMouseDown
EventTypes(1)\EventClass = #kEventClassMouse
EventTypes(1)\EventKind  = #kEventMouseUp

; ----- Intercept raw key down and up events

EventTypes(2)\EventClass = #kEventClassKeyboard
EventTypes(2)\EventKind  = #kEventRawKeyDown
EventTypes(3)\EventClass = #kEventClassKeyboard
EventTypes(3)\EventKind  = #kEventRawKeyUp

; ----- Intercept modifier key changes

EventTypes(4)\EventClass = #kEventClassKeyboard
EventTypes(4)\EventKind  = #kEventRawKeyModifiersChanged

; ----- Intercept mouse wheel movement

EventTypes(5)\EventClass = #kEventClassMouse
EventTypes(5)\EventKind = #kEventMouseWheelMoved

InstallEventHandler_(GetWindowEventTarget_(WindowID(0)), EventHandlerUPP, 6, @EventTypes(), 0, 0)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow

End

DataSection
  Data.L 122, 120,  99, 118,  96,  97,  98, 100, 101, 109
  Data.L 103, 111, 105, 107, 113, 106,  64,  79,  80
EndDataSection
User avatar
Shardik
Addict
Addict
Posts: 2076
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: (crash) Eventhandler and Lion

Post by Shardik »

Unfortunately I have no Lion to test. But I have a quick guess:
try to change the Procedure keyword of the EventHandler to
ProcedureC. Any improvement?
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: (crash) Eventhandler and Lion

Post by jesperbrannmark »

Genius... Yes, it was as easy as that.
User avatar
Shardik
Addict
Addict
Posts: 2076
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: (crash) Eventhandler and Lion

Post by Shardik »

Jesper,

thank you for your fast feedback. I am glad that this problem
is solved. I will change my original posting to ProcedureC too... :wink:
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: (crash) Eventhandler and Lion

Post by jesperbrannmark »

This goes probably for a lot of the snipplets here in the forum. I just updated the sort on listicongadget columnclick example.... (tricks'n'tips section)
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Re: (crash) Eventhandler and Lion

Post by Polo »

This crash was obvious, any PB procedures passed to Carbon API must be cdecl.
Works fine with the fix :wink:
WilliamL
Addict
Addict
Posts: 1259
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: (crash) Eventhandler and Lion

Post by WilliamL »

Code: Select all

ProcedureC EventHandler(*NextEventHandler, Event.L, UserData.L)
It is early...

What qualifies a procedure to have the 'C' suffix (for Carbon)? Is 'CallNextEventHandler_(*NextEventHandler, Event)' the determiner or is there more to it?

I'm a little hazy about this. Maybe it is something that should be in the API thread.
MacBook Pro-M1 (2021), Tahoe 26.2, PB 6.30b6
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3944
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: (crash) Eventhandler and Lion

Post by wilbert »

WilliamL wrote:What qualifies a procedure to have the 'C' suffix (for Carbon)?
To be very short ... nothing :shock:
People just couldn't agree on how a procedure should be called.
http://en.wikipedia.org/wiki/X86_calling_conventions
Many C compilers (and therefore libraries written in C) use cdecl like ProcedureC. Windows Win32 api uses stdcall like Procedure.
On 64 bit things again are different.
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: (crash) Eventhandler and Lion

Post by jesperbrannmark »

Just saw this post in general feature requests
http://www.purebasic.fr/english/viewtop ... =3&t=47512

In the eventhandler we can see the mousewheel up/down. Is there any cleaver way of trapping the other movements (sideways, two fingers, three fingers etc etc)
jesperbrannmark
Enthusiast
Enthusiast
Posts: 536
Joined: Mon Feb 16, 2009 10:42 am
Location: sweden
Contact:

Re: (crash) Eventhandler and Lion

Post by jesperbrannmark »

I have a general question about installing a eventhandler.
From what I understand from my own practice;
A callback/eventhandler on Windows only invokes from a waitwindowevent or windowevent command
A callback/eventhandler on Mac can be invoked at any time

Is this correct?
Basicly, if I am in the middle of a startdrawing() - my current routine/procedure can be broken just to go to the eventhandler.
If this correct or am I wrong?
Fred
Administrator
Administrator
Posts: 18499
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: (crash) Eventhandler and Lion

Post by Fred »

No, event handler are dispatched by WindowEvent/WaitWindowEVent() on all OS
Post Reply