Drawing on canvas from thread crashing on Linux (cross-plat)

Everything else that doesn't fall into one of the other PB categories.
User avatar
Kukulkan
Addict
Addict
Posts: 1421
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Drawing on canvas from thread crashing on Linux (cross-plat)

Post by Kukulkan »

Hi,

this runs fine on Windows, but on Linux it crashes after a few seconds (Kubuntu 14.04). I use PB 5.24 LTS.

Any idea why? As far as I read on the forum and the manual, I'm not allowed to create the GUI in thread (what I don't). But I should be able to draw into the canvas, right?

It is just a test code for a function I like to create. It is not well formatted. Please run Thread-Safe!

Code: Select all

; Include it normally to your project
; To make a notifier, it needs to get initialized once.
; Because of several reasons, please call it after creating all your window gadgets!
;
;  Define CloseGadget.i = not_initNotifier(#NOT_TopRight, ParentWindowID)
;
; The return-value of the not_initNotifier() is the gadget-id of the close-gadget.
; You need to check this in your GUI loop to allow users to close the notifier
; before it runs ot by itself.

; To immediately close the notifier, call
;
;  not_clearNotifier()
;
; In your GUI loop, you have to call this:
;
;  not_UpdateNotifier()
;
; Don't forget to enter a timeout value to your WaitWindowEvent(100) function.
; Without, the timing functions of the notifier will not work as expected!

UsePNGImageDecoder()

; Draws text using wordwrap in a existing StartDrawing context.
; Font size and style and color must be set allready.
; Returns the resulting y position for the end of the text that has been drawn.
Procedure.i GFX_DrawTextWW(PosX.i, PosY.i, Caption.s, PixelWidth.i, MainColor.i, ShadowColor.i)
  Caption.s = Caption.s + " "; to ensure the last charprinted
  
  Protected x.i, Add.i, CRPos.i, CRPos2.i
  Protected StartDraw.i = 1
  Protected DrawLength.i = Len(Caption.s)
  Protected LineHeight.i = TextHeight("gH#|")
  
  Caption.s = ReplaceString(Caption.s, #CRLF$, #CR$)
  Caption.s = ReplaceString(Caption.s, #LF$, #CR$)
  
  DrawingMode(#PB_2DDrawing_Transparent)
  
  Repeat 
    
    While TextWidth(Mid(Caption.s, StartDraw.i, DrawLength.i)) > PixelWidth.i
      DrawLength.i = DrawLength.i - 1
    Wend
    Add.i = 0
    
    CRPos.i = FindString(Mid(Caption.s, StartDraw.i, DrawLength.i), #CR$, 1)
    If CRPos.i > 0
      DrawLength.i = CRPos.i - 1
      Add.i = 1
    EndIf

    If TextWidth(Mid(Caption.s, StartDraw.i, DrawLength.i + 1)) > PixelWidth.i
      For x.i = DrawLength.i To 1 Step -1
        Protected Check.s = Mid(Caption.s, StartDraw.i + x.i, 1) 
        If Check.s = " "
          DrawLength.i = x.i + 1
          Add.i = 0
          Break
        EndIf
        If Check.s = "-"
          DrawLength.i = x.i + 1
          Add.i = 0
          Break
        EndIf
      Next
    EndIf
    
    If MainColor.i <> ShadowColor.i
      DrawText(PosX.i + 1, PosY.i + 1, Trim(Mid(Caption.s, StartDraw.i, DrawLength.i)), ShadowColor.i)
    EndIf
    DrawText(PosX.i, PosY.i, Trim(Mid(Caption.s, StartDraw.i, DrawLength.i)), MainColor.i)
    
    StartDraw.i = StartDraw.i + DrawLength.i + Add.i
    DrawLength.i = Len(Caption.s) - StartDraw.i
    PosY.i = PosY.i + LineHeight.i ; use height maximum
     
  Until DrawLength.i < 1
  ProcedureReturn PosY.i
EndProcedure

;{ image data
DataSection
not_ico_warning:
  Data.b $89,$50,$4E,$47,$0D,$0A,$1A,$0A,$00,$00,$00,$0D,$49,$48,$44,$52
  Data.b $00,$00,$00,$10,$00,$00,$00,$10,$08,$06,$00,$00,$00,$1F,$F3,$FF
  Data.b $61,$00,$00,$00,$04,$73,$42,$49,$54,$08,$08,$08,$08,$7C,$08,$64
  Data.b $88,$00,$00,$00,$09,$70,$48,$59,$73,$00,$00,$0B,$12,$00,$00,$0B
  Data.b $12,$01,$D2,$DD,$7E,$FC,$00,$00,$00,$1C,$74,$45,$58,$74,$53,$6F
  Data.b $66,$74,$77,$61,$72,$65,$00,$41,$64,$6F,$62,$65,$20,$46,$69,$72
  Data.b $65,$77,$6F,$72,$6B,$73,$20,$43,$53,$33,$98,$D6,$46,$03,$00,$00
  Data.b $00,$15,$74,$45,$58,$74,$43,$72,$65,$61,$74,$69,$6F,$6E,$20,$54
  Data.b $69,$6D,$65,$00,$32,$2F,$31,$37,$2F,$30,$38,$20,$9C,$AA,$58,$00
  Data.b $00,$04,$11,$74,$45,$58,$74,$58,$4D,$4C,$3A,$63,$6F,$6D,$2E,$61
  Data.b $64,$6F,$62,$65,$2E,$78,$6D,$70,$00,$3C,$3F,$78,$70,$61,$63,$6B
  Data.b $65,$74,$20,$62,$65,$67,$69,$6E,$3D,$22,$20,$20,$20,$22,$20,$69
  Data.b $64,$3D,$22,$57,$35,$4D,$30,$4D,$70,$43,$65,$68,$69,$48,$7A,$72
  Data.b $65,$53,$7A,$4E,$54,$63,$7A,$6B,$63,$39,$64,$22,$3F,$3E,$0A,$3C
  Data.b $78,$3A,$78,$6D,$70,$6D,$65,$74,$61,$20,$78,$6D,$6C,$6E,$73,$3A
  Data.b $78,$3D,$22,$61,$64,$6F,$62,$65,$3A,$6E,$73,$3A,$6D,$65,$74,$61
  Data.b $2F,$22,$20,$78,$3A,$78,$6D,$70,$74,$6B,$3D,$22,$41,$64,$6F,$62
  Data.b $65,$20,$58,$4D,$50,$20,$43,$6F,$72,$65,$20,$34,$2E,$31,$2D,$63
  Data.b $30,$33,$34,$20,$34,$36,$2E,$32,$37,$32,$39,$37,$36,$2C,$20,$53
  Data.b $61,$74,$20,$4A,$61,$6E,$20,$32,$37,$20,$32,$30,$30,$37,$20,$32
  Data.b $32,$3A,$31,$31,$3A,$34,$31,$20,$20,$20,$20,$20,$20,$20,$20,$22
  Data.b $3E,$0A,$20,$20,$20,$3C,$72,$64,$66,$3A,$52,$44,$46,$20,$78,$6D
  Data.b $6C,$6E,$73,$3A,$72,$64,$66,$3D,$22,$68,$74,$74,$70,$3A,$2F,$2F
  Data.b $77,$77,$77,$2E,$77,$33,$2E,$6F,$72,$67,$2F,$31,$39,$39,$39,$2F
  Data.b $30,$32,$2F,$32,$32,$2D,$72,$64,$66,$2D,$73,$79,$6E,$74,$61,$78
  Data.b $2D,$6E,$73,$23,$22,$3E,$0A,$20,$20,$20,$20,$20,$20,$3C,$72,$64
  Data.b $66,$3A,$44,$65,$73,$63,$72,$69,$70,$74,$69,$6F,$6E,$20,$72,$64
  Data.b $66,$3A,$61,$62,$6F,$75,$74,$3D,$22,$22,$0A,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$78,$6D,$6C,$6E,$73,$3A,$78,$61,$70
  Data.b $3D,$22,$68,$74,$74,$70,$3A,$2F,$2F,$6E,$73,$2E,$61,$64,$6F,$62
  Data.b $65,$2E,$63,$6F,$6D,$2F,$78,$61,$70,$2F,$31,$2E,$30,$2F,$22,$3E
  Data.b $0A,$20,$20,$20,$20,$20,$20,$20,$20,$20,$3C,$78,$61,$70,$3A,$43
  Data.b $72,$65,$61,$74,$6F,$72,$54,$6F,$6F,$6C,$3E,$41,$64,$6F,$62,$65
  Data.b $20,$46,$69,$72,$65,$77,$6F,$72,$6B,$73,$20,$43,$53,$33,$3C,$2F
  Data.b $78,$61,$70,$3A,$43,$72,$65,$61,$74,$6F,$72,$54,$6F,$6F,$6C,$3E
  Data.b $0A,$20,$20,$20,$20,$20,$20,$20,$20,$20,$3C,$78,$61,$70,$3A,$43
  Data.b $72,$65,$61,$74,$65,$44,$61,$74,$65,$3E,$32,$30,$30,$38,$2D,$30
  Data.b $32,$2D,$31,$37,$54,$30,$32,$3A,$33,$36,$3A,$34,$35,$5A,$3C,$2F
  Data.b $78,$61,$70,$3A,$43,$72,$65,$61,$74,$65,$44,$61,$74,$65,$3E,$0A
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$3C,$78,$61,$70,$3A,$4D,$6F
  Data.b $64,$69,$66,$79,$44,$61,$74,$65,$3E,$32,$30,$30,$38,$2D,$30,$33
  Data.b $2D,$32,$34,$54,$31,$39,$3A,$30,$30,$3A,$34,$32,$5A,$3C,$2F,$78
  Data.b $61,$70,$3A,$4D,$6F,$64,$69,$66,$79,$44,$61,$74,$65,$3E,$0A,$20
  Data.b $20,$20,$20,$20,$20,$3C,$2F,$72,$64,$66,$3A,$44,$65,$73,$63,$72
  Data.b $69,$70,$74,$69,$6F,$6E,$3E,$0A,$20,$20,$20,$20,$20,$20,$3C,$72
  Data.b $64,$66,$3A,$44,$65,$73,$63,$72,$69,$70,$74,$69,$6F,$6E,$20,$72
  Data.b $64,$66,$3A,$61,$62,$6F,$75,$74,$3D,$22,$22,$0A,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$78,$6D,$6C,$6E,$73,$3A,$64,$63
  Data.b $3D,$22,$68,$74,$74,$70,$3A,$2F,$2F,$70,$75,$72,$6C,$2E,$6F,$72
  Data.b $67,$2F,$64,$63,$2F,$65,$6C,$65,$6D,$65,$6E,$74,$73,$2F,$31,$2E
  Data.b $31,$2F,$22,$3E,$0A,$20,$20,$20,$20,$20,$20,$20,$20,$20,$3C,$64
  Data.b $63,$3A,$66,$6F,$72,$6D,$61,$74,$3E,$69,$6D,$61,$67,$65,$2F,$70
  Data.b $6E,$67,$3C,$2F,$64,$63,$3A,$66,$6F,$72,$6D,$61,$74,$3E,$0A,$20
  Data.b $20,$20,$20,$20,$20,$3C,$2F,$72,$64,$66,$3A,$44,$65,$73,$63,$72
  Data.b $69,$70,$74,$69,$6F,$6E,$3E,$0A,$20,$20,$20,$3C,$2F,$72,$64,$66
  Data.b $3A,$52,$44,$46,$3E,$0A,$3C,$2F,$78,$3A,$78,$6D,$70,$6D,$65,$74
  Data.b $61,$3E,$0A,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$0A,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$0A,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$35,$1D,$52,$64,$00,$00,$00,$F9
  Data.b $49,$44,$41,$54,$38,$8D,$A5,$93,$31,$6A,$03,$31,$10,$45,$9F,$82
  Data.b $20,$97,$70,$1D,$C8,$6D,$7C,$03,$EF,$36,$DA,$33,$49,$CD,$CA,$37
  Data.b $48,$97,$53,$B8,$0E,$4E,$E9,$6E,$CB,$25,$10,$56,$C4,$64,$52,$AC
  Data.b $26,$C8,$89,$AC,$60,$F2,$E1,$83,$34,$33,$FF,$F3,$47,$20,$28,$20
  Data.b $D0,$09,$C8,$1F,$1C,$4B,$8D,$D1,$C3,$02,$1D,$30,$5A,$EF,$69,$E1
  Data.b $3C,$0C,$00,$F1,$5E,$A4,$37,$26,$CB,$67,$E8,$66,$90,$E4,$BD,$CC
  Data.b $D0,$64,$31,$B3,$26,$99,$A0,$9B,$40,$DE,$BD,$97,$09,$2E,$A8,$F8
  Data.b $59,$2F,$66,$47,$4E,$20,$6F,$DE,$CB,$09,$7E,$51,$51,$EB,$A9,$C6
  Data.b $26,$E0,$13,$48,$8D,$BD,$6B,$3D,$D5,$D8,$05,$38,$AF,$8F,$78,$15
  Data.b $B5,$9E,$6A,$FE,$9F,$20,$01,$F3,$E1,$70,$B3,$81,$6A,$6C,$CA,$71
  Data.b $6E,$35,$50,$8D,$5D,$80,$0F,$EA,$7B,$3E,$1B,$53,$A9,$AE,$50,$4D
  Data.b $33,$C1,$56,$04,$80,$A7,$8A,$91,$6A,$EE,$12,$74,$C7,$10,$D8,$38
  Data.b $47,$CA,$45,$65,$B9,$42,$C9,$8D,$73,$1C,$43,$20,$41,$34,$00,$7B
  Data.b $D8,$01,$F1,$C1,$39,$5E,$43,$B8,$1A,$1B,$A0,$98,$89,$3B,$E8,$BF
  Data.b $B3,$F9,$6C,$F2,$E8,$5C,$D3,$E0,$25,$8B,$5D,$FE,$4C,$17,$CB,$A9
  Data.b $49,$D3,$01,$E2,$00,$BD,$5E,$BE,$00,$89,$EC,$D3,$24,$71,$B1,$76
  Data.b $AD,$00,$00,$00,$00,$49,$45,$4E,$44,$AE,$42,$60,$82
EndDataSection

DataSection
not_ico_info:
  Data.b $89,$50,$4E,$47,$0D,$0A,$1A,$0A,$00,$00,$00,$0D,$49,$48,$44,$52
  Data.b $00,$00,$00,$10,$00,$00,$00,$10,$08,$06,$00,$00,$00,$1F,$F3,$FF
  Data.b $61,$00,$00,$00,$04,$73,$42,$49,$54,$08,$08,$08,$08,$7C,$08,$64
  Data.b $88,$00,$00,$00,$09,$70,$48,$59,$73,$00,$00,$0B,$12,$00,$00,$0B
  Data.b $12,$01,$D2,$DD,$7E,$FC,$00,$00,$00,$1C,$74,$45,$58,$74,$53,$6F
  Data.b $66,$74,$77,$61,$72,$65,$00,$41,$64,$6F,$62,$65,$20,$46,$69,$72
  Data.b $65,$77,$6F,$72,$6B,$73,$20,$43,$53,$33,$98,$D6,$46,$03,$00,$00
  Data.b $00,$15,$74,$45,$58,$74,$43,$72,$65,$61,$74,$69,$6F,$6E,$20,$54
  Data.b $69,$6D,$65,$00,$32,$2F,$31,$37,$2F,$30,$38,$20,$9C,$AA,$58,$00
  Data.b $00,$04,$11,$74,$45,$58,$74,$58,$4D,$4C,$3A,$63,$6F,$6D,$2E,$61
  Data.b $64,$6F,$62,$65,$2E,$78,$6D,$70,$00,$3C,$3F,$78,$70,$61,$63,$6B
  Data.b $65,$74,$20,$62,$65,$67,$69,$6E,$3D,$22,$20,$20,$20,$22,$20,$69
  Data.b $64,$3D,$22,$57,$35,$4D,$30,$4D,$70,$43,$65,$68,$69,$48,$7A,$72
  Data.b $65,$53,$7A,$4E,$54,$63,$7A,$6B,$63,$39,$64,$22,$3F,$3E,$0A,$3C
  Data.b $78,$3A,$78,$6D,$70,$6D,$65,$74,$61,$20,$78,$6D,$6C,$6E,$73,$3A
  Data.b $78,$3D,$22,$61,$64,$6F,$62,$65,$3A,$6E,$73,$3A,$6D,$65,$74,$61
  Data.b $2F,$22,$20,$78,$3A,$78,$6D,$70,$74,$6B,$3D,$22,$41,$64,$6F,$62
  Data.b $65,$20,$58,$4D,$50,$20,$43,$6F,$72,$65,$20,$34,$2E,$31,$2D,$63
  Data.b $30,$33,$34,$20,$34,$36,$2E,$32,$37,$32,$39,$37,$36,$2C,$20,$53
  Data.b $61,$74,$20,$4A,$61,$6E,$20,$32,$37,$20,$32,$30,$30,$37,$20,$32
  Data.b $32,$3A,$31,$31,$3A,$34,$31,$20,$20,$20,$20,$20,$20,$20,$20,$22
  Data.b $3E,$0A,$20,$20,$20,$3C,$72,$64,$66,$3A,$52,$44,$46,$20,$78,$6D
  Data.b $6C,$6E,$73,$3A,$72,$64,$66,$3D,$22,$68,$74,$74,$70,$3A,$2F,$2F
  Data.b $77,$77,$77,$2E,$77,$33,$2E,$6F,$72,$67,$2F,$31,$39,$39,$39,$2F
  Data.b $30,$32,$2F,$32,$32,$2D,$72,$64,$66,$2D,$73,$79,$6E,$74,$61,$78
  Data.b $2D,$6E,$73,$23,$22,$3E,$0A,$20,$20,$20,$20,$20,$20,$3C,$72,$64
  Data.b $66,$3A,$44,$65,$73,$63,$72,$69,$70,$74,$69,$6F,$6E,$20,$72,$64
  Data.b $66,$3A,$61,$62,$6F,$75,$74,$3D,$22,$22,$0A,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$78,$6D,$6C,$6E,$73,$3A,$78,$61,$70
  Data.b $3D,$22,$68,$74,$74,$70,$3A,$2F,$2F,$6E,$73,$2E,$61,$64,$6F,$62
  Data.b $65,$2E,$63,$6F,$6D,$2F,$78,$61,$70,$2F,$31,$2E,$30,$2F,$22,$3E
  Data.b $0A,$20,$20,$20,$20,$20,$20,$20,$20,$20,$3C,$78,$61,$70,$3A,$43
  Data.b $72,$65,$61,$74,$6F,$72,$54,$6F,$6F,$6C,$3E,$41,$64,$6F,$62,$65
  Data.b $20,$46,$69,$72,$65,$77,$6F,$72,$6B,$73,$20,$43,$53,$33,$3C,$2F
  Data.b $78,$61,$70,$3A,$43,$72,$65,$61,$74,$6F,$72,$54,$6F,$6F,$6C,$3E
  Data.b $0A,$20,$20,$20,$20,$20,$20,$20,$20,$20,$3C,$78,$61,$70,$3A,$43
  Data.b $72,$65,$61,$74,$65,$44,$61,$74,$65,$3E,$32,$30,$30,$38,$2D,$30
  Data.b $32,$2D,$31,$37,$54,$30,$32,$3A,$33,$36,$3A,$34,$35,$5A,$3C,$2F
  Data.b $78,$61,$70,$3A,$43,$72,$65,$61,$74,$65,$44,$61,$74,$65,$3E,$0A
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$3C,$78,$61,$70,$3A,$4D,$6F
  Data.b $64,$69,$66,$79,$44,$61,$74,$65,$3E,$32,$30,$30,$38,$2D,$30,$33
  Data.b $2D,$32,$34,$54,$31,$39,$3A,$30,$30,$3A,$34,$32,$5A,$3C,$2F,$78
  Data.b $61,$70,$3A,$4D,$6F,$64,$69,$66,$79,$44,$61,$74,$65,$3E,$0A,$20
  Data.b $20,$20,$20,$20,$20,$3C,$2F,$72,$64,$66,$3A,$44,$65,$73,$63,$72
  Data.b $69,$70,$74,$69,$6F,$6E,$3E,$0A,$20,$20,$20,$20,$20,$20,$3C,$72
  Data.b $64,$66,$3A,$44,$65,$73,$63,$72,$69,$70,$74,$69,$6F,$6E,$20,$72
  Data.b $64,$66,$3A,$61,$62,$6F,$75,$74,$3D,$22,$22,$0A,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$78,$6D,$6C,$6E,$73,$3A,$64,$63
  Data.b $3D,$22,$68,$74,$74,$70,$3A,$2F,$2F,$70,$75,$72,$6C,$2E,$6F,$72
  Data.b $67,$2F,$64,$63,$2F,$65,$6C,$65,$6D,$65,$6E,$74,$73,$2F,$31,$2E
  Data.b $31,$2F,$22,$3E,$0A,$20,$20,$20,$20,$20,$20,$20,$20,$20,$3C,$64
  Data.b $63,$3A,$66,$6F,$72,$6D,$61,$74,$3E,$69,$6D,$61,$67,$65,$2F,$70
  Data.b $6E,$67,$3C,$2F,$64,$63,$3A,$66,$6F,$72,$6D,$61,$74,$3E,$0A,$20
  Data.b $20,$20,$20,$20,$20,$3C,$2F,$72,$64,$66,$3A,$44,$65,$73,$63,$72
  Data.b $69,$70,$74,$69,$6F,$6E,$3E,$0A,$20,$20,$20,$3C,$2F,$72,$64,$66
  Data.b $3A,$52,$44,$46,$3E,$0A,$3C,$2F,$78,$3A,$78,$6D,$70,$6D,$65,$74
  Data.b $61,$3E,$0A,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$0A,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$0A,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
  Data.b $20,$20,$20,$20,$20,$20,$20,$20,$35,$1D,$52,$64,$00,$00,$03,$0C
  Data.b $49,$44,$41,$54,$38,$8D,$5D,$93,$4D,$68,$54,$77,$14,$C5,$7F,$FF
  Data.b $F7,$5E,$66,$26,$E3,$4C,$32,$49,$26,$86,$29,$F1,$03,$32,$71,$66
  Data.b $44,$EC,$4C,$28,$56,$A5,$85,$6E,$2C,$82,$11,$DC,$59,$D0,$66,$D1
  Data.b $42,$37,$BA,$B0,$DD,$58,$8A,$0B,$17,$56,$DA,$45,$69,$16,$15,$BA
  Data.b $E8,$07,$24,$B5,$10,$2C,$B4,$88,$B8,$E8,$AA,$AD,$D0,$86,$A6,$D1
  Data.b $89,$60,$27,$EA,$C4,$7C,$37,$31,$93,$BC,$4C,$66,$5E,$66,$DE,$C7
  Data.b $FF,$BD,$D7,$45,$C2,$D4,$F4,$C2,$DD,$DC,$73,$38,$1C,$EE,$BD,$47
  Data.b $F0,$BF,$CA,$5C,$BE,$D9,$1B,$D0,$D4,$0F,$05,$1C,$57,$15,$91,$06
  Data.b $70,$3D,$7F,$D2,$87,$DF,$6D,$E9,$7E,$52,$F8,$F4,$DC,$D3,$17,$F9
  Data.b $02,$C0,$F7,$7D,$00,$B2,$57,$46,$BE,$EE,$6A,$8F,$BC,$D3,$7F,$24
  Data.b $CD,$C1,$EE,$0E,$3A,$A3,$21,$00,$4A,$55,$93,$BF,$17,$D6,$B8,$F3
  Data.b $E7,$24,$CF,$75,$E3,$9B,$FC,$B5,$B3,$EF,$02,$08,$21,$FE,$13,$C8
  Data.b $5D,$19,$29,$F4,$1F,$4D,$A7,$4F,$BF,$92,$A4,$6A,$7B,$2C,$54,$1D
  Data.b $74,$53,$02,$D0,$19,$D6,$D8,$13,$0D,$10,$D6,$04,$B7,$FF,$2A,$72
  Data.b $67,$74,$72,$F2,$C1,$B5,$B3,$19,$21,$04,$2A,$C0,$4F,$32,$F3,$55
  Data.b $FF,$91,$F4,$9B,$FD,$7D,$3D,$3C,$2A,$D5,$79,$B2,$56,$A7,$62,$49
  Data.b $96,$E6,$75,$A6,$9F,$AE,$50,$DE,$B4,$59,$F7,$04,$75,$E9,$F3,$5A
  Data.b $B2,$0B,$5F,$28,$F1,$0F,$86,$7F,$DD,$F3,$FC,$DE,$0F,$B7,$D5,$CC
  Data.b $E5,$9B,$BD,$89,$F6,$96,$6F,$DF,$3B,$91,$E5,$51,$A9,$C6,$62,$C5
  Data.b $C2,$F3,$7C,$CA,$6B,$9B,$A4,$5B,$03,$7C,$74,$E6,$20,$95,$B2,$49
  Data.b $71,$C5,$C0,$52,$14,$6C,$D7,$E3,$58,$CF,$6E,$C6,$8A,$4B,$7D,$C1
  Data.b $BE,$53,$DF,$2B,$01,$4D,$BD,$7E,$32,$97,$C4,$B0,$24,$8B,$65,$13
  Data.b $57,$7A,$B8,$D2,$C3,$36,$25,$F1,$68,$10,$80,$95,$AA,$85,$AA,$2A
  Data.b $B8,$D2,$63,$4E,$37,$31,$2C,$C9,$C9,$5C,$92,$80,$A6,$5E,$D7,$04
  Data.b $1C,$4A,$25,$DA,$98,$5A,$AD,$61,$DB,$6E,$63,$BB,$D2,$76,$19,$7F
  Data.b $A6,$33,$FE,$4C,$A7,$EC,$41,$AC,$23,$82,$74,$5C,$24,$30,$A7,$9B
  Data.b $A4,$12,$6D,$08,$38,$A4,$A8,$8A,$48,$C7,$77,$05,$59,$D0,$EB,$5B
  Data.b $84,$ED,$AE,$6E,$D4,$F8,$F8,$AD,$C3,$9C,$7F,$7D,$3F,$66,$CD,$D9
  Data.b $81,$2D,$AE,$D7,$89,$EF,$0A,$A2,$2A,$22,$AD,$8D,$CF,$94,$D8,$A8
  Data.b $3B,$4C,$97,$6A,$D4,$B6,$1D,$38,$96,$A4,$C5,$DB,$3A,$6D,$71,$D9
  Data.b $A0,$B8,$B2,$89,$8E,$D2,$70,$17,$0D,$6A,$BC,$BA,$B7,$85,$F1,$99
  Data.b $12,$0A,$90,$9F,$5B,$35,$78,$29,$D2,$84,$63,$4B,$1C,$5B,$62,$99
  Data.b $0E,$89,$B6,$66,$00,$9E,$2C,$55,$50,$55,$A5,$81,$39,$B6,$64,$5F
  Data.b $2C,$C8,$FC,$AA,$01,$90,$57,$80,$FC,$D8,$D4,$32,$07,$3A,$C3,$78
  Data.b $D2,$C3,$B1,$5D,$2C,$D3,$21,$95,$88,$02,$F0,$F8,$9F,$2A,$BE,$69
  Data.b $63,$5B,$12,$C7,$76,$F1,$A5,$47,$6F,$BC,$99,$B1,$A9,$E5,$86,$C0
  Data.b $D5,$5B,$A3,$05,$62,$21,$8D,$9E,$8E,$10,$D2,$91,$78,$9E,$4F,$D5
  Data.b $74,$00,$F8,$6C,$20,$47,$24,$B4,$E5,$4E,$3A,$92,$D4,$EE,$30,$CD
  Data.b $4D,$0A,$B7,$46,$0B,$00,$57,$55,$1E,$DE,$DD,$30,$33,$27,$62,$75
  Data.b $DB,$3B,$7A,$3A,$BB,$17,$A3,$EE,$A0,$6F,$3A,$4C,$CC,$96,$F9,$F2
  Data.b $E7,$22,$43,$BF,$4D,$63,$7A,$3E,$01,$4D,$E1,$70,$77,$2B,$C7,$93
  Data.b $ED,$0C,$DD,$2B,$F0,$70,$7E,$79,$90,$E1,$8B,$23,$8D,$57,$16,$03
  Data.b $37,$1E,$9C,$7A,$39,$99,$3D,$77,$2C,$43,$D5,$94,$4C,$CC,$96,$99
  Data.b $5A,$31,$68,$52,$15,$7A,$BA,$22,$A4,$12,$51,$62,$E1,$26,$BE,$FB
  Data.b $A3,$C0,$DD,$89,$62,$DE,$1F,$BA,$90,$DB,$91,$05,$00,$31,$70,$E3
  Data.b $F3,$D6,$E6,$D0,$A5,$33,$B9,$03,$F4,$ED,$EF,$A4,$BB,$2D,$02,$C0
  Data.b $C2,$BA,$C1,$FD,$99,$12,$3F,$DE,$7F,$4C,$C5,$B4,$06,$FD,$A1,$0B
  Data.b $EF,$EF,$08,$D3,$8E,$7A,$FB,$8B,$7D,$C0,$25,$E0,$0D,$20,$BB,$3D
  Data.b $CD,$03,$BF,$00,$83,$0C,$5F,$9C,$7D,$91,$FE,$2F,$18,$04,$85,$B2
  Data.b $E0,$E4,$9A,$40,$00,$00,$00,$00,$49,$45,$4E,$44,$AE,$42,$60,$82
EndDataSection

;} ------ end image data ------

Enumeration
  #NOT_TopLeft
  #NOT_TopRight
  #NOT_BottomRight
  #NOT_BottomLeft
EndEnumeration

#NOT_Margin = 60 ; margin of notifier window to screen border in pixels
#NOT_Margin_Top   = 4  ; margin between text
#NOT_Margin_Left  = 18 ; margin left (image is this - 2 px)
#NOT_Margin_Right = 4  ; margin right

#NOT_Color_WindowBackground = $F0F0F0 ; $BBGGRR
#NOT_Color_LabelColor       = $303030 ; $BBGGRR
#NOT_Color_LabelColorWarn   = $2020B0 ; $BBGGRR
#NOT_Color_LabelColorShadow = $E0E0E0 ; $BBGGRR

Structure now_entry
  Caption.s
  StartTime.i
  EndTime.i
  Color.i
EndStructure

Structure not_window
  Visible.b
  WindowID.i
  Position.i
  LastCheck.i
  CanvasGadgetID.i
  ;LineHeight.i
  FontID.i
  RotOffset.f
  WinHeight.i
  List Entries.now_entry()
EndStructure

Global not_data.not_window ; holds all global notifier data

Procedure not_Thread(param.i)
  Protected y.i, textHeight.i, allHeight.i, newY.i
  Repeat 
    Delay(50)
    If ListSize(not_data\Entries()) < 1 And not_data\Visible = #False
      Delay(50)
      Continue
    EndIf
    
    With not_data
      
      If \Visible = #False
        \Visible = #True
        \RotOffset = GadgetHeight(\CanvasGadgetID)
        \WinHeight = GadgetHeight(\CanvasGadgetID)
        ResizeWindow(\WindowID, #PB_Ignore, #PB_Ignore, #PB_Ignore, \WinHeight)
        HideWindow(\WindowID, #False, #PB_Window_NoActivate)
      EndIf
      
      imgWarn.i = CatchImage(#PB_Any, ?not_ico_warning)
      imgInfo.i = CatchImage(#PB_Any, ?not_ico_info)
      
      If imgWarn.i = 0 Or imgInfo.i = 0
        Debug "error catching images!"
        End
      EndIf
      
      StartDrawing(CanvasOutput(\CanvasGadgetID))
      Box(0, 0, GadgetWidth(\CanvasGadgetID), GadgetHeight(\CanvasGadgetID), #NOT_Color_WindowBackground)
      DrawingFont(FontID(\FontID))
      y.i = \RotOffset
      allHeight.i = 0
      ForEach \Entries()
        If y.i < GadgetHeight(\CanvasGadgetID)
          DrawingMode(#PB_2DDrawing_AlphaBlend)
          If \Entries()\Color = #NOT_Color_LabelColorWarn
            DrawImage(ImageID(imgWarn.i), 0, y.i + #NOT_Margin_Top + 1, #NOT_Margin_Left - 2, #NOT_Margin_Left - 2)
          Else
            DrawImage(ImageID(imgInfo.i), 0, y.i + #NOT_Margin_Top + 1, #NOT_Margin_Left - 2, #NOT_Margin_Left - 2)
          EndIf
          DrawingMode(#PB_2DDrawing_Default)
          newY.i = GFX_DrawTextWW(#NOT_Margin_Left, 
                                  y.i + #NOT_Margin_Top, 
                                  \Entries()\Caption, 
                                  GadgetWidth(\CanvasGadgetID) - #NOT_Margin_Left - #NOT_Margin_Right, 
                                  \Entries()\Color, 
                                  #NOT_Color_LabelColorShadow)
          allHeight.i = allHeight.i + (newY.i - y.i)
          y.i = newY.i
        Else
          If ElapsedMilliseconds() > \Entries()\EndTime
            DeleteElement(\Entries(), 1)
          EndIf
        EndIf
      Next
      StopDrawing()
      
      \RotOffset = \RotOffset - 1
      If \RotOffset < -allHeight.i
        \RotOffset = GadgetHeight(\CanvasGadgetID)
      EndIf
      
      If ListSize(not_data\Entries()) < 1
        If \WinHeight > 0
          \WinHeight = \WinHeight - 3
          ResizeWindow(\WindowID, #PB_Ignore, #PB_Ignore, #PB_Ignore, \WinHeight)
        Else
          \Visible = #False
          HideWindow(\WindowID, #True)
        EndIf
      EndIf
      
      FreeImage(imgWarn.i)
      FreeImage(imgInfo.i)
      
    EndWith
    
  ForEver
EndProcedure

; Call once initially to initialize the notifier window
Procedure not_initNotifier(Position.i,
                           ParentWindowID.i)
                           
  ExamineDesktops()
  
  ; calculate position
  Protected wW = DesktopWidth(0) * 0.15  ; Width  = 15% of Desktop
  Protected wH = DesktopHeight(0) * 0.05 ; Height = 25% of Desktop
  Protected wX, wY
  
  Select Position.i
    Case #NOT_TopLeft
      wX = #NOT_Margin
      wY = #NOT_Margin
    Case #NOT_TopRight
      wX = DesktopWidth(0) - #NOT_Margin - wW
      wY = #NOT_Margin
    Case #NOT_BottomRight
      wX = DesktopWidth(0) - #NOT_Margin - wW
      wY = DesktopHeight(0) - #NOT_Margin - wH
    Case #NOT_BottomLeft
      wX = #NOT_Margin
      wY = DesktopHeight(0) - #NOT_Margin - wH
  EndSelect
  
  With not_data
  
    If \WindowID = 0
      ; #########################
      ; Generate notifier window
      ; #########################
      \FontID = LoadFont(#PB_Any, "Arial", 8)
      
      ; Create window
      \WindowID = OpenWindow(#PB_Any, wX, wY, wW, wH, "", 
                             #PB_Window_Invisible | #PB_Window_BorderLess | #PB_Window_NoActivate,
                             WindowID(ParentWindowID.i))
      
      \CanvasGadgetID = CanvasGadget(#PB_Any, 0, 0, wW, wH)
      \Visible = #False
    Else
      ; Window already exists. Just re-poition.
      ResizeWindow(\WindowID, wX, wY, wW, wH)
    EndIf
    
    \Position         = Position.i
    
    SetWindowColor(\WindowID, #NOT_Color_WindowBackground)
    
    CreateThread(@not_Thread(), 0)
    
    ProcedureReturn \CanvasGadgetID
  EndWith
EndProcedure

; Call to clean and close the notifier
Procedure not_clearNotifier(quick.b = #False)
  ; cleanup
  With not_data
    ClearList(\Entries())
    If quick.b = #True
      ; for a quick close
      \Visible = #False
      HideWindow(\WindowID, #True, #PB_Window_NoActivate)
    EndIf
  EndWith
EndProcedure

; Call to add a new notifier
Procedure not_showNotifier(Message.s, Warning.i = #False)
  With not_data
    
    ; check for duplicate entry
    ForEach \Entries()
      If \Entries()\Caption = Message.s
        \Entries()\StartTime = ElapsedMilliseconds(); update timestamp
        ProcedureReturn
      EndIf
    Next
    
    ; add entry to list
    AddElement(\Entries())
    \Entries()\Caption = Message.s
    \Entries()\StartTime = ElapsedMilliseconds()
    \Entries()\EndTime = ElapsedMilliseconds() + 4000 + Len(Message.s) * 50
    \Entries()\Color = #NOT_Color_LabelColor
    If Warning.i = #True
      \Entries()\Color = #NOT_Color_LabelColorWarn
    EndIf
    
    \WinHeight = GadgetHeight(\CanvasGadgetID)
    ResizeWindow(\WindowID, #PB_Ignore, #PB_Ignore, #PB_Ignore, \WinHeight)
  
  EndWith

EndProcedure

; Test code. Uncomment to run tests on the notifier
If OpenWindow(1, 100, 200, 195, 260, "Notifier Main Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  Define Add.i = ButtonGadget(#PB_Any, 10,10,180,20, "Add Notifier!")
  Define Clear.i = ButtonGadget(#PB_Any, 10,40,180,20, "Clear Notifier!")
  Define Counter.i = 0
  Define Quit = 0
  Define Test.s = "wort1 wort2 wort3 wort4 wort5 wort6 wort7 wort8 wort9 wort0 wort1 wort2 wort3 wort4 wort5 wort6 wort7 wort8 wort9 wort0 "
  
  Define CloseGadget.i = not_initNotifier(#NOT_BottomRight, 1)
  
  Repeat
    Define Event = WaitWindowEvent(100)

    If Event = #PB_Event_Gadget
      Select EventGadget()
        Case Add.i
          Counter = Counter + 1
          Type.i = Random(1, 0)
          not_showNotifier(Str(counter) + " " + Left(Test.s, Random(Len(Test.s), 20)), Type.i)
        Case Clear.i
          If EventType() = #PB_EventType_LeftClick
            not_ClearNotifier()
          EndIf
        Case CloseGadget.i
          If EventType() = #PB_EventType_LeftClick
            not_ClearNotifier()
          EndIf
      EndSelect
    EndIf
    
    If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
      Quit = 1
    EndIf
    
  Until Quit = 1
  
EndIf

End
Any idea why it crashes? Did not test on MacOS, but has to work there, too.

Kukulkan
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: Drawing on canvas from thread crashing on Linux (cross-p

Post by Keya »

Kukulkan wrote: I'm not allowed to create the GUI in thread (what I don't). But I should be able to draw into the canvas, right?
I dont know the answer to that sorry, although you mightve answered it yourself!
I got tired of UI-related issues with threads in Mac and Linux (for example you cant even call MessageRequester from another thread in Linux)
so now for all my programs i just use PostEvent to tell the main message loop what to do. It doesnt make a mess of the main loop because from there i simply call out to another procedure to keep it clean and modular.
Maybe its not the best way, i dont know, but its working well for me and im no longer having those issues!
http://purebasic.fr/english/viewtopic.p ... 39#p469639
User avatar
Kukulkan
Addict
Addict
Posts: 1421
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Drawing on canvas from thread crashing on Linux (cross-p

Post by Kukulkan »

Hello,

just an update: On MacOS it does not crash. But after the Window was hidden one, it never is displayed any more even if I call HideWindow() again to re-display it.

@Keya: Thanks for the hint, but my main thread is not working fine to scroll something smooth. I also do not like to use the main thread for a job that is definitely a thread job. I mean, hey, this is what threads are for!

Best,

Kukulkan
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: Drawing on canvas from thread crashing on Linux (cross-p

Post by Keya »

Kukulkan wrote:I also do not like to use the main thread for a job that is definitely a thread job. I mean, hey, this is what threads are for!
yes but im just wondering that it might be the problem because drawing on a canvas probably still counts as a UI modification?
ill be keeping my eye on this thread because im still learning this too, but my understanding is that you can still do all the work in your worker thread, but any UI updates need to be sent through the main thread. but maybe im wrong
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Drawing on canvas from thread crashing on Linux (cross-p

Post by Trond »

Drawing into a widget (the canvas) is definetely "doing GUI". GTK is thread-aware but not thread-safe. You can use GTK in threads, but only from one thread at a time. This means you can access GTK calls from any thread provided you do appropriate locking.

Appropriate locking in this case is wrapping your GTK calls in gdk_threads_enter_(); and gdk_threads_leave_();

This does not apply to GTK callbacks that are called from the main thread, because GTKs main loop calls gdk_threads_enter_() right before calling the callback, then gdk_threads_leave_() right afterwards.

More information: http://blogs.operationaldynamics.com/an ... -awareness
User avatar
heartbone
Addict
Addict
Posts: 1058
Joined: Fri Apr 12, 2013 1:55 pm
Location: just outside of Ferguson

Re: Drawing on canvas from thread crashing on Linux (cross-p

Post by heartbone »

Thank you Trond for your excellent solution description.
This is important to know.
Keep it BASIC.
User avatar
Kukulkan
Addict
Addict
Posts: 1421
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Drawing on canvas from thread crashing on Linux (cross-p

Post by Kukulkan »

Hello,

@Trond: Thank you. Yes, this works here (need to call gdk_threads_init_() first in main thread). Sadly, these functions are marked as deprecated since GTK 3.6. So it is not recommended to use them :-(

I'm just creating some general event handler to allow me flexible registration of various GUI jobs in main thread in a general way and reducing the code needed for implementation. If it is worth mentioning, I will post it here. Sadly, it forces me to put more time consuming things into threads (like opening and reading bigger files or fetch some internet data)...

I just found that QT is having the same issues with threads. Strange. I wonder how they all do progressbars and other notifications then...
Fred
Administrator
Administrator
Posts: 18538
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Drawing on canvas from thread crashing on Linux (cross-p

Post by Fred »

Usually all GUI stuff (progress bar etc) are done in the main thread using timer (AddWindowTimer()). The event loop in the main thread should never be blocked by a long computation, which should be done in a thread and you can use PostMessage() from any thread to interact with the main queue.
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: Drawing on canvas from thread crashing on Linux (cross-p

Post by Keya »

Fred wrote:you can use PostMessage() from any thread to interact with the main queue.
or PostEvent() for cross-OS! :D is working well for me so far
Fred
Administrator
Administrator
Posts: 18538
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Drawing on canvas from thread crashing on Linux (cross-p

Post by Fred »

That's what I meant :)
User avatar
Kukulkan
Addict
Addict
Posts: 1421
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Drawing on canvas from thread crashing on Linux (cross-p

Post by Kukulkan »

But how to handle modal dialogues like file-requesters and message boxes (continue/cancel etc)?

It is not recommended to run them from a thread but calling them from the main thread is blocking all displaying then (eg progress bars, because no events are handled in this time). I do not really see this as a final solution...
Post Reply