Logitech display include file (for G15 keyboard, etc)
Posted: Mon Nov 12, 2007 12:19 am
Here is an include file for writing programs for Logitech devices that have screens, eg the G15 keyboard.
It's basically an update of HeX0R's code that he posted somewhere ages ago. If you want some examples of use then look up his post.
The update is to make it work properly with the latest .lib file... I've tested it in an executable on versions of windows that don't support the devices and/or don't have device drivers installed, all works ok (the calls exit with an error code - no crashes!).
The only thing I haven't been able to test (and would like to know what happens if possible) is an executable with the x86 version of the .lib on a x64 machine.
Code: Select all
; lgLcd.pbi
; Main Include for playing with the Logitech Display devices such as the G15 Keyboard
; You need to copy the 'lgLcd.lib' (v1.03 or above) to the same dir as this Header.
; Based upon lglcd.h (c)Logitech & G15_Header.pbi (c)HeX0R
; Updated by DoubleDutch
; Invalid handle definitions
#LGLCD_INVALID_CONNECTION=-1
#LGLCD_INVALID_DEVICE=-1
; Soft-Button masks
#LGLCDBUTTON_BUTTON0 =1<<0
#LGLCDBUTTON_BUTTON1 =1<<1
#LGLCDBUTTON_BUTTON2 =1<<2
#LGLCDBUTTON_BUTTON3 =1<<3
Structure lgLcdDeviceDesc
Width.l
Height.l
Bpp.l
NumSoftButtons.l
EndStructure
Structure lgLcdDeviceDescEx
deviceFamilyId.l
deviceDisplayName.c[#MAX_PATH]
Width.l
Height.l
Bpp.l
NumSoftButtons.l
Reserved1.l
Reserved2.l
EndStructure
; lgLcdBitmap
#LGLCD_BMP_FORMAT_160x43x1=1
#LGLCD_BMP_WIDTH=160
#LGLCD_BMP_HEIGHT=43
Structure lgLcdBitmapHeader
Format.l
EndStructure
Structure lgLcdBitmap160x43x1
hdr.lgLcdBitmapHeader
pixels.b[#LGLCD_BMP_WIDTH*#LGLCD_BMP_HEIGHT]
EndStructure
; Priorities
#LGLCD_PRIORITY_IDLE_NO_SHOW=0
#LGLCD_PRIORITY_BACKGROUND=64
#LGLCD_PRIORITY_NORMAL=128
#LGLCD_PRIORITY_ALERT=255
Macro LGLCD_SYNC_UPDATE(priority)
($80000000|priority)
EndMacro
Macro LGLCD_SYNC_COMPLETE_WITHIN_FRAME(priority)
($c0000000|priority)
EndMacro
Macro LGLCD_ASYNC_UPDATE(priority)
priority
EndMacro
; Foreground mode for client applications
#LGLCD_LCD_FOREGROUND_APP_NO=#False
#LGLCD_LCD_FOREGROUND_APP_YES=#True
; Device family definitions
#LGLCD_DEVICE_FAMILY_KEYBOARD_G15 =1<<0
#LGLCD_DEVICE_FAMILY_SPEAKERS_Z10 =1<<1
#LGLCD_DEVICE_FAMILY_JACKBOX =1<<2
#LGLCD_DEVICE_FAMILY_LCDEMULATOR_G15 =1<<3
#LGLCD_DEVICE_FAMILY_RAINBOW =1<<4
#LGLCD_DEVICE_FAMILY_OTHER =$80000000
; Capabilities of applets connecting to LCD Manager
#LGLCD_APPLET_CAP_BASIC =0
#LGLCD_APPLET_CAP_CAN_CLOSE_DEVICE =1<<0
#LGLCD_APPLET_CAP_CAN_CLOSE_CONNECTION =1<<1
#LGLCD_APPLET_CAP_CAN_CLOSE_AND_REOPEN_DEVICE =1<<2
#LGLCD_APPLET_CAP_CAN_RUN_ON_MULTIPLE_DEVICES =1<<3
;Callback used To notify client of soft button change
;Declare.l lgLcdOnSoftButtonsCB(device.l,dwButtons.l,pContext.l)
;Callback used To allow client To pop up a "configuration panel"
;Declare.l lgLcdOnConfigureCB(connection.l,pContect.l)
Structure lgLcdConfigureContext
*configCallback ; Set to NULL if not configurable
*configContext
EndStructure
Structure lgLcdNotificationContext
*notificationCallback ; Set to NULL if not notifiable
*notifyContext
EndStructure
Structure lgLcdConnectContext
*appFriendlyName ; "Friendly name" display in the listing
isPersistent.l ; determines whether this connection persists in the list
isAutostartable.l ; determines whether the client can be started by LCDMon
onConfigure.lgLcdConfigureContext
connection.l ; Connection handle
EndStructure
; New additions added in 1.03 revision
Structure lgLcdConnectContextEx Extends lgLcdConnectContext
dwAppletCapabilitiesSupported.l ; Or'd combination of LGLCD_APPLET_CAP_... defines
dwReserved1.l
onNotify.lgLcdNotificationContext ; <- strange because Notification is depreciated as of 1.03 revision
EndStructure
; lgLcdOpenContext
Structure lgLcdSoftbuttonsChangedContext
*softbuttonsChangedCallback ; Set to NULL if no softbutton notifications are needed
*softbuttonsChangedContext
EndStructure
Structure lgLcdOpenContext
connection.l
index.l ; Device index to open
onSoftbuttonsChanged.lgLcdSoftbuttonsChangedContext
device.l ; Device handle
EndStructure
Import "lgLcd.lib"
; Initialize the library by calling this function.
lgLcdInit()
; Must be called to release the library and free all allocated structures.
lgLcdDeInit()
; Connect as a client to the LCD subsystem. Provide name to be displayed for user when viewing the user interface of the LCD module,
; as well as a configuration callback and context, and a flag that states whether this client is startable by LCDMon
CompilerIf #PB_Compiler_Unicode
lgLcdConnect.l(*ctx.lgLcdConnectContext) As "_lgLcdConnectW@4"
CompilerElse
lgLcdConnect.l(*ctx.lgLcdConnectContext) As "_lgLcdConnectA@4"
CompilerEndIf
; Must be called to release the connection and free all allocated resources
lgLcdDisconnect.l(connection.l)
; New additions added in 1.03 revision of API. Call this method to setup which device families the applet is interested
; in. After this call, the applet can use lgLcdEnumerateEx to determine if a device from the device family wanted is found.
lgLcdSetDeviceFamiliesToUse.l(connection.l,dwDeviceFamiliesSupported.l,dwReserved1.l)
; To determine all connected LCD devices supported by this library, and their capabilities. Start with index 0,
; and increment by one, until the library returns an error (WHICH?).
lgLcdEnumerate.l(connection.l,index.l,*description.lgLcdDeviceDesc)
lgLcdEnumerateEx.l(connection.l,index.l,*description.lgLcdDeviceDescEx)
; Opens the LCD at position=index. Library sets the device parameter to its internal reference to the device.
; Calling application provides the device handle in all calls that access the LCD.
lgLcdOpen.l(*ctx.lgLcdOpenContext)
; Closes the LCD. Must be paired with lgLcdOpen.
lgLcdClose.l(device.l)
; Reads the state of the soft buttons for the device.
lgLcdReadSoftButtons.l(device.l,*buttons)
; Provides a bitmap to be displayed on the LCD. The priority field further describes the way in which the bitmap is to be applied.
lgLcdUpdateBitmap.l(device.l, *bitmap.lgLcdBitmapHeader,priority.l)
; Sets the calling application as the shown application on the LCD, and stops
; any type of rotation among other applications on the LCD.
lgLcdSetAsLCDForegroundApp.l(device.l,foregoundYesNoFlag.l)
EndImport
Procedure.l Img2G15(Image,*bitmap.lgLcdBitmap160x43x1,Invers=0)
Protected A,B,x,y,w,h,d,Result,hDC,*bmi.BITMAPINFO,*Buffer,Add
If Not IsImage(Image)
ProcedureReturn #False
EndIf
w=ImageWidth(Image)
h=ImageHeight(Image)
d=ImageDepth(Image)
; fix widths and heights
If d=1
d=8
EndIf
If w>#LGLCD_BMP_WIDTH
w=#LGLCD_BMP_WIDTH
h=h*#LGLCD_BMP_WIDTH/ImageWidth(Image)
If h>#LGLCD_BMP_HEIGHT
h=#LGLCD_BMP_HEIGHT
w=w*#LGLCD_BMP_HEIGHT/ImageHeight(Image)
EndIf
ElseIf h>#LGLCD_BMP_HEIGHT
h=#LGLCD_BMP_HEIGHT
w=w*#LGLCD_BMP_HEIGHT/ImageHeight(Image)
If w>#LGLCD_BMP_WIDTH
w=#LGLCD_BMP_WIDTH
h=h*#LGLCD_BMP_WIDTH/ImageWidth(Image)
EndIf
EndIf
If w<>ImageWidth(Image) Or h<>ImageHeight(Image)
ResizeImage(Image,w,h)
EndIf
*bitmap\hdr\Format=#LGLCD_BMP_FORMAT_160x43x1
hDC=StartDrawing(ImageOutput(Image))
If hDC
*bmi=AllocateMemory(SizeOf(BITMAPINFO)+255*SizeOf(RGBQUAD))
If *bmi
*bmi\bmiHeader\biSize=SizeOf(BITMAPINFOHEADER)
*bmi\bmiheader\biWidth=w
*bmi\bmiheader\biHeight=-h
*bmi\bmiheader\biPlanes=1
*bmi\bmiheader\biBitCount=d
*bmi\bmiheader\biCompression=#BI_RGB
*Buffer=AllocateMemory(w*h*(d/8))
If Not *Buffer
StopDrawing()
Else
Result=GetDIBits_(hDC,ImageID(Image),0,h,*Buffer,*bmi,#DIB_RGB_COLORS)
StopDrawing()
If Result
Add=0
Select d
Case 8
For y=0 To #LGLCD_BMP_HEIGHT-1
For x=0 To #LGLCD_BMP_WIDTH-1
If y>=h Or x>=w
B=255
Else
A=PeekB(*Buffer+Add)&$ff
A=PeekL(*bmi\bmiColors+A*SizeOf(RGBQUAD))
B=(A&$ff)+((A>>8)&$ff)+((A>>16)&$ff)
Add+1
EndIf
If Invers
*bitmap\pixels[y*#LGLCD_BMP_WIDTH+x]=B/3
Else
*bitmap\pixels[y*#LGLCD_BMP_WIDTH+x]=255-(B/3)
EndIf
Next
Next
Case 16
For y=0 To #LGLCD_BMP_HEIGHT-1
For x=0 To #LGLCD_BMP_WIDTH-1
If y>=h Or x>=w
B=510
Else
A=PeekW(*Buffer+Add)
B=(A&$ff)+((A>>8)&$ff)
Add+2
EndIf
If Invers
*bitmap\pixels[y*#LGLCD_BMP_WIDTH+x]=B/2
Else
*bitmap\pixels[y*#LGLCD_BMP_WIDTH+x]=255-(B/2)
EndIf
Next
Next
Case 24
For y=0 To #LGLCD_BMP_HEIGHT-1
For x=0 To #LGLCD_BMP_WIDTH-1
If y>=h Or x>=w
B=765
Else
A=PeekL(*Buffer+Add)
B=(A&$ff)+((A>>8)&$ff)+((A>>16)&$ff)
Add+3
EndIf
If Invers
*bitmap\pixels[y*#LGLCD_BMP_WIDTH+x]=B/3
Else
*bitmap\pixels[y*#LGLCD_BMP_WIDTH+x]=255-(B/3)
EndIf
Next
Next
Case 32
For y=0 To #LGLCD_BMP_HEIGHT-1
For x=0 To #LGLCD_BMP_WIDTH-1
If y>=h Or x>=w
B=765
Else
A=PeekL(*Buffer+Add)
B=(A&$ff)+((A>>8)&$ff)+((A>>16)&$ff)
Add+4
EndIf
If Invers
*bitmap\pixels[y*#LGLCD_BMP_WIDTH+x]=B/3
Else
*bitmap\pixels[y*#LGLCD_BMP_WIDTH+x]=255-(B/3)
EndIf
Next
Next
EndSelect
EndIf
FreeMemory(*Buffer)
EndIf
FreeMemory(*bmi)
EndIf
EndIf
ProcedureReturn Result
EndProcedure The only thing I haven't been able to test (and would like to know what happens if possible) is an executable with the x86 version of the .lib on a x64 machine.