Quick start

Documentation. First post is always kind of manual page, being continuously updated by author. Following posts are discussion about the topic.
Post Reply
admin
Site Admin
Posts: 735
Joined: 01 Nov 2010, 13:00
Location: Prague, Czech republic
Contact:

Quick start

Post by admin » 19 Apr 2015, 21:42

This simple script shows typical use of old application HidMacros. It's recommended to run this sample only if you have 2 keyboards attached as one of these keyboards will be (almost) blocked. However you can still run it with one keyboard (and mouse giving you the option to close LuaMacros and have keyboard unblocked again).

So here we go.

Download LuaMacros zip file, extract to any folder on your disc. There's no installation needed to run LuaMacros, but you need to have all files extracted. Start luamacros.exe and paste this script into editor:

Code: Select all

-- assign logical name to macro keyboard
lmc_assign_keyboard('MACROS');

-- define callback for whole device
lmc_set_handler('MACROS',function(button, direction)
  if (direction == 1) then return end  -- ignore down
  if     (button == string.byte('C')) then lmc_spawn("calc")
  elseif (button == string.byte('N')) then lmc_spawn("notepad", "C:\\test.txt")
  elseif (button == string.byte('H')) then lmc_send_keys('Hello world')
  else print('Not yet assigned: ' .. button) 
  end
end)
Or you can open this script using first button and opening file samples/quickstart.lua. Then click on Run icon. The script will get executed.
Purpose of this script is to define one keyboard as "macro" keyboard and assign some function to 3 keys on this keyboard.
So once you start the script LuaMacros will ask you to identify the macros keyboard by pressing any button on this keyboard. This is what command lmc_assign_keyboard does.
Once you press any key at the keyboard the keyboard will be "hooked" to trigger macros and won't work as usual (keys pressed on this keyboard won't reach active application - e.g. you can not type in Notepad with this keyboard). Other keyboards will work.
Now if you press C on this macro keyboard, windows calculator will start. If you press N notepad will start and will open file test.txt from C:\. This is done just to demonstrate command line arguments - the file usually won't exist so Notepad will ask you if this is new file and should be created.
Finally if you press H the active application (maybe that Notepad) will receive "Hello world" keystrokes.
Any other key from macro keyboard won't do anything, just info message will be logged.
Petr Medek
LUAmacros author

User avatar
Xupicor
Posts: 7
Joined: 27 Jun 2015, 12:45

Re: Quick start

Post by Xupicor » 27 Jun 2015, 14:58

So your sample works fine, while my simple script doesn't:

Code: Select all

clear()
lmc_device_set_name('KB', '2BA672CB')
lmc_print_devices()

lmc_set_handler('KB', 2, 0, function(button, direction)
  print('callback for whole keyboard: ' .. button .. ', direction: ' .. direction)
end)


All I get is this:

Code: Select all

<unassigned>  :  Controller (XBOX 360 For Windows) [0] :  game
<unassigned>  :  \\?\HID#VID_046D&PID_C31C&MI_00#8&1F22FCF0&0&0000#{884B96C3-56EF-11D1-BC8C-00A0C91405DD} [65601] :  keyboard
KB  :  \\?\ACPI#PNP0303#4&2BA672CB&0#{884B96C3-56EF-11D1-BC8C-00A0C91405DD} [720959] :  keyboard
Total number of devices: 3
The hooked keyboard works normally, i.e. keyboard events are not caught by the handler function at all.The keyboard in question is connected through PS/2, but if I hook the USB keyboard it still doesn't work.

What am I doing wrong?

edit:
Ah, I think I confused myself when I tried different arguments for lmc_set_handler(). I might have some other problem initially, then started meddling and...
Well, in short - this:

Code: Select all

lmc_set_handler('KB', function(button, direction)
  print('callback for whole keyboard: ' .. button .. ', direction: ' .. direction)
end) 
works as expected. Sorry to waste your time, I usually resolve my problems before posting them... I just didn't see the problem it until I posted it on the forum. Feel free to delete this post if you wish the thread to be cleaner. :)

cristiano_pruneri
Posts: 14
Joined: 19 Jul 2013, 12:43

Re: Quick start

Post by cristiano_pruneri » 17 Nov 2017, 21:24

I have a question... would it be possible for

lmc_print_devices()

to return the text that is prints, as a string in Lua?

I am thinking about building a Java "thing" (ugh) to have an UI for handling various types of action, depending on the active window executable, with an automatic version-keeping system.

I already wrote a small lua program that sends the keystrokes as an http GET with keycode and direction (only once, on "down" ),

Code: Select all

function toUnicode(a)
a1,a2,a3,a4 = a:byte(1, -1)
ans = string.format ("%%%02X", a1)
n = a2
if (n)
then
ans = ans .. string.format ("%%%02X", n)
end
n = a3
if (n)
then
ans = ans .. string.format ("%%%02X", n)
end
n = a4
if (n)
then
ans = ans .. string.format ("%%%02X", n)
end
return ans
end

function urlencode(str)
if (str) then
str = string.gsub (str, "\n", "\r\n")
str = string.gsub (str, "\\", "/")
str = string.gsub (str, "([^%w ])", toUnicode)
str = string.gsub (str, " ", "+")
end
return str
end


map={}
localPort=1000

baseHandler= function(pad, ignoreBlockNum, button, direction)

if (ignoreBlockNum) then
   if (button==144) then
      return
   end
end

if(map[pad]== direction)    then
           return
      end

       map[pad]= direction
       request= 'http://127.0.0.1:'..localPort..'/?source=' .. pad .. '&k=' .. button .. '&d=' .. direction

       -- Potentially a source of problems, and I have access to the active Window title in java anyway
       tt=urlencode(lmc_get_window_title())
       request=request..'&t='.. tt

    --  print(request)
    
      -- TODO check that the server is up by looking that the answer is "OK"
       print(lmc_http_get(request, 1))

end

function addPad(pad, ignoreBlockNum)
      lmc_assign_keyboard(pad);
      lmc_set_handler(pad,function(button, direction)
           baseHandler(pad, ignoreBlockNum,button, direction)
      end)
end


function addDevice(pad, deviceID, ignoreBlockNum)
      lmc_device_setname(pad, deviceID);
      lmc_set_handler(pad,function(button, direction)
           baseHandler(pad, ignoreBlockNum,button, direction)
      end)
end

lmc_print_devices()


----------------------------------------------------------------------------------------------------------------------------------------
-- this final part should end in a Java-generated file, then Java would Launch LuaMacros. 
-- In java I already have around some code to find a free socket
localPort=32000

-- For the moment, I identify the pads this way, but it would be nice that I had a way for knowing which one is which
-- beyond opening hidmacros and looking what id it prints when I push a button... is there? 

addPad('PAD_1', false)
addPad('PAD_2', true)
addPad('PAD_3', true)
addPad('PAD_4', false)

however I would like my someday-to-be Java monstrosity to be able to check if the "USB tree" is coherent with the one it knows
(I have a "contetxt switcher" for HidMacros that does just that... when I save the Hidmacros config after changing an usb port, it pop ups to notify that unknown defaults have appeared, I choose which is what, and the thing goes on to replace it in every app-dependent config as It loads them).

Having access to the list of devices would make my life much simpler.

I can't seem to find a way to install the INet package and build LuaMacros in Lazarus (a whole day lost ), or I would try to do it myself (also, Pascal is not really my cup of tea).

Also, I have a question - I know that LM is a singleton, but, if I try spawn two instances of it, using separate scripts as -r option, does the second call invoke replacing the loaded script in the open Lua?

Or, should I need it, I will be back at killing and relaunching LuaMacros, like I had to do with HidMacros?

cristiano_pruneri
Posts: 14
Joined: 19 Jul 2013, 12:43

Re: Quick start

Post by cristiano_pruneri » 18 Nov 2017, 20:42

I have found a workaround, based on code from the "MacroRecorder"...

admin
Site Admin
Posts: 735
Joined: 01 Nov 2010, 13:00
Location: Prague, Czech republic
Contact:

Re: Quick start

Post by admin » 20 Nov 2017, 09:09

For feature requests (mapped devices in variable) the best way is to open issue at github - to have it tracked. Implement this feature should not be a problem.
Regarding starting second instance with -r... not sure I would expect the second instance is not started at all if one is already running. So no script is replaced. But didn't check.
Petr Medek
LUAmacros author

cristiano_pruneri
Posts: 14
Joined: 19 Jul 2013, 12:43

Re: Quick start

Post by cristiano_pruneri » 21 Nov 2017, 03:25

My bad - I have found a way around it, based on the "tricks" in the "Macrorecorder" -

In reality, if there is a way to remove already assigned handlers, I would already be good with all that I need to use LuaMacros as a "device driver" - for the moment, I just avoid assign more than one handler on an already "listened" keyboard and when I "detach" a keyboard in the Java GUI I simply tell LM to print the keys (the keyboard becomes just a bit sluggish).

Hopefully my days of killing an re-launching HIDmacros are gone.

As for the other thing, I have a habit of doing Java apps that, to save time on the GUI building, lay dormient after closed and receive a TCP call from a sister instance that tries to be launched. Not sure if there is a more elegan way, but it makes my hierarchically ordered "send to" (something I missed sorely when I finally deciided to switch to Winn 7) reasonably fast.

I thought it could work similarly...

In reality, I tried accidentally to launch two together and the results are pretty odd... the handlers keep listening to the keyboards - so I see data entering through the http server in the Java - yet the key presses are not trapped, so the event goes through.

Post Reply