Grafiktablet/Stift Input über Wintab API

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Grafiktablet/Stift Input über Wintab API

Beitrag von Danilo »

Inspiriert von diesem Thread von LCD, habe ich nun einmal probiert
mein eigenes Grafiktablet über das Wintab Interface auszulesen.

Sollte im Prinzip mit allen Geräten funktionieren die Wintab benutzen.
Ich konnte es allerdings nur mit meinem 'Trust Wireless Scroll Tablet 1200-V2' testen.

Im SDK bei Wacom findet man alle Infos (Beispiele, Doku). Das hier ist nur schnell
zusammengehackt zum testen und auslesen der Koordinaten X/Y/Z und der Druck-
werte der Stiftspitze.

Code: Alles auswählen

;
; pen/tablet input test for wacom tablets and compatible devices
; using WINTAB32.dll
;
; by Danilo, 2008/06/12
;
; Wacom SDK: http://www.wacomeng.com/devsupport/ibmpc/downloads.html
;
Structure LOGCONTEXTA
	lcName.b[40];
	lcOptions.l;
	lcStatus.l;
	lcLocks.l;
	lcMsgBase.l;
	lcDevice.l;
	lcPktRate.l;
	lcPktData.l;
	lcPktMode.l;
	lcMoveMask.l;
	lcBtnDnMask.l;
	lcBtnUpMask.l;
	lcInOrgX.l;
	lcInOrgY.l;
	lcInOrgZ.l;
	lcInExtX.l;
	lcInExtY.l;
	lcInExtZ.l;
	lcOutOrgX.l;
	lcOutOrgY.l;
	lcOutOrgZ.l;
	lcOutExtX.l;
	lcOutExtY.l;
	lcOutExtZ.l;
	lcSensX.l;

	lcSensY.l;
	lcSensZ.l;
	lcSysMode.l;
	lcSysOrgX.l;
	lcSysOrgY.l;
	lcSysExtX.l;
	lcSysExtY.l;
	lcSysSensX.l;
	lcSysSensY.l;
EndStructure

Structure PACKET
  pkButtons.l
  pkX.l
  pkY.l
  pkZ.l
  pkNormalPressure.l
  pkTangentPressure.l
EndStructure

#WTI_DEFCTX    = 3
#WTI_DEFSYSCTX = 4


#CTX_NAME		    = 1
#CTX_OPTIONS		= 2
#CTX_STATUS		  = 3
#CTX_LOCKS		  = 4
#CTX_MSGBASE		= 5
#CTX_DEVICE		  = 6
#CTX_PKTRATE		= 7
#CTX_PKTDATA		= 8
#CTX_PKTMODE		= 9
#CTX_MOVEMASK	  = 10
#CTX_BTNDNMASK	= 11
#CTX_BTNUPMASK	= 12
#CTX_INORGX		  = 13
#CTX_INORGY		  = 14
#CTX_INORGZ		  = 15
#CTX_INEXTX		  = 16
#CTX_INEXTY		  = 17
#CTX_INEXTZ		  = 18
#CTX_OUTORGX		= 19
#CTX_OUTORGY		= 20
#CTX_OUTORGZ		= 21
#CTX_OUTEXTX		= 22
#CTX_OUTEXTY		= 23
#CTX_OUTEXTZ		= 24
#CTX_SENSX		  = 25
#CTX_SENSY		  = 26
#CTX_SENSZ		  = 27
#CTX_SYSMODE		= 28
#CTX_SYSORGX		= 29
#CTX_SYSORGY		= 30
#CTX_SYSEXTX		= 31
#CTX_SYSEXTY		= 32
#CTX_SYSSENSX	  = 33
#CTX_SYSSENSY	  = 34
#CTX_MAX			  = 34

#CXO_MESSAGES  = 4

#WT_DEFBASE    = $7FF0
#WT_PACKET     = #WT_DEFBASE + 0
#WT_INFOCHANGE = #WT_DEFBASE + 6

#PK_BUTTONS           = $0040 ;/* button information */
#PK_X                 = $0080 ;/* x axis */
#PK_Y                 = $0100 ;/* y axis */
#PK_Z                 = $0200 ;/* z axis */
#PK_NORMAL_PRESSURE   = $0400 ;/* normal Or tip pressure */
#PK_TANGENT_PRESSURE  = $0800 ;/* tangential Or barrel pressure */


; ---------------------------------------
; ---------------------------------------
; ---------------------------------------

  Prototype.l WTInfo_(wCategory, nIndex, *lpOutput)
  Prototype.l WTOpen_(hWnd, *lpLogCtx, fEnable)
  Prototype.l WTPacket_(hCtx, wSerial, *lpPkt)
  Prototype.l WTClose_(hCtx)

  If OpenLibrary(0, "Wintab32.dll")
   
    WTInfo.WTInfo_     = GetFunction(0, "WTInfoA")
    WTOpen.WTOpen_     = GetFunction(0, "WTOpenA")
    WTPacket.WTPacket_ = GetFunction(0,"WTPacket")
    WTClose.WTClose_   = GetFunction(0,"WTClose")
    
    If WTInfo(0, 0, 0)
      OpenWindow(0,0,0,800,600,"tablet",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
      CreateGadgetList(WindowID(0))

      info.LOGCONTEXTA
      WTInfo(#WTI_DEFCTX,0,@info)

      #PACKETDATA = #PK_X | #PK_Y | #PK_Z | #PK_BUTTONS | #PK_NORMAL_PRESSURE | #PK_TANGENT_PRESSURE
      ;#PACKETMODE = #PK_BUTTONS | #PK_NORMAL_PRESSURE | #PK_TANGENT_PRESSURE
      #PACKETMODE = 0

      info\lcOptions  = #CXO_MESSAGES
      info\lcMsgBase  = #WT_DEFBASE
      info\lcPktData  = #PACKETDATA
      info\lcPktMode  = #PACKETMODE
      info\lcMoveMask = #PACKETDATA
      info\lcBtnUpMask = info\lcBtnDnMask
      
      info\lcOutOrgX = 0
      info\lcOutOrgY = 0
      info\lcOutExtX = 10000
      info\lcOutExtY = 10000


      hCtx = WTOpen(WindowID(0),@info,1)

      TextGadget(0,0,0,WindowWidth(0),25,Name$)
      SetGadgetText(0,PeekS(@info\lcName))

      For i = 1 To 6
        TextGadget(i,5,20+i*30,145,25,"------------------")
      Next i
      
      w = WindowWidth(0)-150
      h = WindowHeight(0)-25
      ImageGadget(10,150,25,w,h,CreateImage(0,w,h))
      
      Repeat
        Select WaitWindowEvent()
          Case #PB_Event_CloseWindow
            Break
          Case #WM_MOUSEMOVE
          Case #WT_PACKET
            WTPacket(EventlParam(),EventwParam(), @pkt.PACKET)
            ;If pkt\pkButtons
              SetGadgetText(1,"pkButtons: "       + RSet(Hex(pkt\pkButtons),8,"0") )
            ;EndIf
            SetGadgetText(2,"pkX: "               + Str(pkt\pkX               ))
            SetGadgetText(3,"pkY: "               + Str(pkt\pkY               ))
            SetGadgetText(4,"pkZ: "               + Str(pkt\pkZ               ))
            SetGadgetText(5,"pkNormalPressure: "  + Str(pkt\pkNormalPressure  ))
            SetGadgetText(6,"pkTangentPressure: " + Str(pkt\pkTangentPressure ))
            If StartDrawing(ImageOutput(0))
              If pkt\pkNormalPressure
                size = pkt\pkNormalPressure / 30
                size + 2
              Else
                size = 2
              EndIf
              Circle( MulDiv_(pkt\pkX,ImageWidth(0),10000), ImageHeight(0)-MulDiv_(pkt\pkY,ImageHeight(0),10000), size,RGB($FF,$FF,$00))
              StopDrawing()
              SetGadgetState(10,ImageID(0))
            EndIf
          ;Case #WT_INFOCHANGE
        EndSelect
      ForEver
      
      WTClose(hCtx)

    Else
      MessageRequester("ERROR","WTInfo = 0! Tablet ready?")
    EndIf

    CloseLibrary(0)
  Else
    MessageRequester("ERROR","Cant open WINTAB32.dll! Tablet ready?")
  EndIf
Das Gerät/Tablet muß angeschlossen und funktionsfähig sein, sonst gibt
WTInfo() 0 zurück, da kein benutzbares Gerät gefunden.

Ich würde mich freuen zu erfahren ob es mit Euren Tablets/Pens auch geht.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
dige
Beiträge: 1236
Registriert: 08.09.2004 08:53

Beitrag von dige »

Genial, sowas hätte ich mir schon vor 5 Jahren gewünscht. Ich habe zwar
noch ein Aiptek GraTabl rumliegen, aber mangels fehlenden PS/2 Port nicht
mehr am laufen..
"Papa, ich laufe schneller - dann ist es nicht so weit."
LCD
Beiträge: 107
Registriert: 23.01.2008 13:13
Wohnort: Wien

Beitrag von LCD »

Danielo! Ich liebe Dich!!! Vielen Dank!!!
Es funktioniert mit dem Aiptek HyperPen 8000 bestens. Das gehört auf jeden Fall ins Code Archiv rein :allright:.
PB 4.61Beta1 32/64Bit. AMD FX6100, 8 GB RAM, ATI Radeon 5750, Win7 64 (64 bit ist mist weil 16-Bit Programme wie MakeTZX nicht mehr darauf funktionieren).
Benutzeravatar
Xaby
Beiträge: 2144
Registriert: 12.11.2005 11:29
Wohnort: Berlin + Zehdenick
Kontaktdaten:

Beitrag von Xaby »

@LCD
ich schließe mich an. Danilo, ich glaube ich muss mich mal ransetzen und eine Fanpage für dich gestalten :mrgreen:

Die Software, du du uns hier präsentierst, ist die einzige mir bekannte Software, die den Stift unabhängig von der Maus nutzen kann.

Selbst Corel Painter, was ja eigentlich das NonPlusUltra sein sollte und auch PhotoShop blockieren die Maus bzw. interpretieren den Stift wie die Maus und die Maus wie einen Stift mit fester Härter.

Aber mit dem Ding, was du da gemacht hast, da kann man zwei unabhängige Anwendungen laufen lassen. Zum Beispiel Kinder auf einem zweiten Bildschirm zeichnen lassen und selbst mit der Maus in Anwednungen klicken.

Oder mit der Maus Icons verschieben und wirklich mit dem Stift nur zeichnen, ohne jedes Mal den Cursor dann wieder neu suchen zu müssen bzw. zum Icon verschieben wieder erst umständlich aus dem Malprogramm zu müssen mit dem Stift.

Einfach genial :allright: :allright: :allright: :allright: :allright:
Kinder an die Macht http://scratch.mit.edu/
Antworten