Advertisement
faubiguy

Monitor Terminal

Mar 27th, 2013
627
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.90 KB | None | 0 0
  1. local redirectPath = '/rom/programs/redirect' -- Change to redirect API path if installed elsewhere!
  2. local redirectAPI, loadError = loadfile(redirectPath)
  3.  
  4. if not redirectAPI then
  5.     print('Unable to load terminal redirection API')
  6.     print(loadError == 'File not found' and
  7.         'No file exists at '..redirectPath..'. Edit the first line in this program to the location of the redirect API.' or
  8.         'Syntax error in redirect API.'
  9.     )
  10.     return
  11. end
  12.  
  13. local newTerm=setmetatable({},{__index=_G})
  14. setfenv(redirectAPI, newTerm)
  15. if not pcall(redirectAPI) then
  16.     print('Error occured in redirect API')
  17.     return
  18. end
  19. newTerm = newTerm.newTerm;
  20.  
  21. local side, programPath = ... -- Temp
  22. local debugOn = false;
  23. local args = {select(3,...)}
  24.  
  25. if select('#',...) < 2 then
  26.     print('Usage: ',fs.getName(shell.getRunningProgram()),' <side/name of monitor> <program to run> [arguments for program]')
  27.     return
  28. end
  29. if peripheral.getType(side) ~= 'monitor' then
  30.     print('Error: There is no monitor on side ',side)
  31.     return
  32. end
  33. if not shell.resolveProgram(programPath) then
  34.     print('Error: There is no program at ',programPath)
  35.     return
  36. end
  37.  
  38. local monitor = peripheral.wrap(side);
  39. if not monitor.isColor() then
  40.     print('Monitor must be advanced')
  41.     return
  42. end
  43. if (monitor.getSize()) < 50 or select(2,monitor.getSize()) < 33 then
  44.     print('Monitor too small. Must be at least 5x5 blocks (width x height)')
  45.     return
  46. end
  47.  
  48. local function debug(...) if not debugOn then return end print(...) end
  49.  
  50. --local side;
  51. local mouseButton = 1;
  52. --[[local shiftPressed = false;
  53. local ctrlPressed = false;
  54. local altPressed = false;]]
  55. local keysPressed = {[29]=false, [42]=false, [56]=false}; -- 42=shift, 56=alt, 29=ctrl
  56. local lastPressed = {[29]=0, [42]=0, [56]=0}
  57. local capsLock = false;
  58. local programTerm = newTerm(1, 1, 50, 18, monitor);
  59. local filter = nil;
  60.  
  61. local function colorSetup()
  62.     monitor.setBackgroundColor(colors.black)
  63.     monitor.setTextColor(colors.white)
  64.     monitor.setCursorBlink(false)
  65. end
  66.  
  67. colorSetup()
  68. monitor.clear()
  69.  
  70. -- Program mangement stuff --
  71. --[[local program = coroutine.create(setfenv(function() shell.run(programPath) end,
  72.     setmetatable({
  73.         peripheral = setmetatable({
  74.            
  75.         }, {__index = peripheral})
  76.     },{__index = _G}))
  77. )]]
  78.  
  79. local program = coroutine.create(function() shell.run(programPath, unpack(args)) end);
  80.  
  81. local function resume(...)
  82.     assert(coroutine.status(program) ~= 'dead')
  83.     term.redirect(programTerm)
  84.     local ok;
  85.     ok, filter = coroutine.resume(program,...)
  86.     term.restore()
  87.     assert(ok)
  88. end
  89.  
  90. -- Virtual keyboard and mouse handling --
  91.  
  92. local keyboard = {
  93.     'F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 ',
  94.     '',
  95.     'A B C D E F G H I J K L M N O P Q R S T',
  96.     'U V W X Y Z 1 2 3 4 5 6 7 8 9 0 ! @ # $',
  97.     '% ^ & * ( ) - _ = + | { } [ ] : ; " \' <',
  98.     '> , . ? / \\ ` ~ Space  Enter  Backspace',
  99.     '',
  100.     'Ctrl Shift Alt     Insert Home PageUp',
  101.     'Caps  Tab  Meta    Delete End  PageDown',
  102. }
  103.  
  104. local arrowKeys = {
  105.     '  /\\',
  106.     '  ||',
  107.     '/-/\\-\\',
  108.     '\\-\\/-/',
  109.     '  ||',
  110.     '  \\/',
  111. }
  112.  
  113. local keyCodes = {
  114.     Ctrl = 29, Shift = 42, Alt = 56, Caps = 58,
  115.     ['1']=2,  ['2']=3,  ['3']=4, ['4']=5, ['5']=6,
  116.     ['6']=7,  ['7']=8,  ['8']=9, ['9']=10,['0']=11,
  117.     ['!']=2,  ['@']=3,  ['#']=4, ['$']=5, ['%']=6,
  118.     ['^']=7,  ['&']=8,  ['*']=9, ['(']=10,[')']=11,
  119.     ['`']=41, ['~']=144,['-']=12,['_']=12,['=']=13,
  120.     ['+']=13, ['[']=26, ['{']=26,['}']=27,[']']=27,
  121.     ['\\']=43,['|']=43, [';']=39,[':']=39,["'"]=40,
  122.     ['"']=40, [',']=51, ['<']=51,['.']=52,['>']=52,
  123.     ['/']=53, ['/']=53,
  124.     PageDown=209,PageUp=201,Meta=219,
  125. }
  126.  
  127. local function drawKeyboard()
  128.     for i=1,9 do
  129.         monitor.setCursorPos(3,23+i)
  130.         monitor.write(keyboard[i])
  131.     end
  132.     monitor.setCursorPos(44,24)
  133.     monitor.write('Arrows:')
  134.     for i=1,6 do
  135.         monitor.setCursorPos(44,25+i)
  136.         monitor.write(arrowKeys[i])
  137.     end
  138.     for i=1,3 do
  139.         monitor.setCursorPos(44 + (i==1 and 0 or 1),19+i)
  140.         monitor.write(({'Scroll:','Up','Down'})[i])
  141.     end
  142. end
  143. drawKeyboard()
  144.  
  145. local function updateKeyDisplay()
  146.     colorSetup()
  147.     monitor.setCursorPos(3, 20)
  148.     monitor.write('Shift: ' .. (keysPressed[42] and 'Down' or 'Up  '))
  149.     monitor.setCursorPos(3, 21)
  150.     monitor.write('Alt: ' .. (keysPressed[56] and 'Down' or 'Up  '))
  151.     monitor.setCursorPos(3, 22)
  152.     monitor.write('Ctrl: ' .. (keysPressed[29] and 'Down' or 'Up  '))  
  153. end
  154. updateKeyDisplay();
  155.  
  156. local function getArrowKey(x,y)
  157.     --[[if y >= 26 and y <= 29 and x >= 45 and x <= ({46,48,49,48})[y-25] then
  158.         return ({200,203,205,208})[y-25]
  159.     end]]
  160.     y = y - 25;
  161.     x = x - 43;
  162.     if x<1 or y<1 or x>6 or y>6 then
  163.         return nil;
  164.     end
  165.     x = (x - (x-1)%2 + 1)/2;
  166.     y = (y - (y-1)%2 + 1)/2;
  167.     if x==1 then
  168.         return y==2 and 203 or nil;
  169.     elseif x==2 then
  170.         return y==1 and 200 or y==3 and 208 or nil;
  171.     elseif x==3 then
  172.         return y==2 and 205 or nil;
  173.     end
  174.     return nil;
  175. end
  176.  
  177. local function getKey(x,y)
  178.     local arrowKey = getArrowKey(x,y);
  179.     if arrowKey then return arrowKey end
  180.     y = y - 23
  181.     x = x - 2
  182.     if x<1 or y<1 or x>39 or y > 9 or y==2 or y==7 then
  183.         return nil
  184.     end
  185.     debug('Touched keyboard')
  186.     local row = keyboard[y]
  187.     local startPos = x;
  188.    
  189.     while startPos > 1 and row:sub(startPos-1,startPos-1) ~= ' ' do
  190.         startPos=startPos-1;
  191.     end
  192.     while x<39 and row:sub(x+1,x+1) ~= ' ' do
  193.         x=x+1
  194.     end
  195.     local key=row:sub(startPos,x);
  196.     local char = nil;
  197.     if x==startPos then
  198.         char = (keysPressed[42] or capsLock) and key or key:lower();
  199.     end
  200.     key = keys[key:lower()] or keyCodes[key];
  201.     debug('Key: ',key or 'nil',', Char: ',char or 'nil')
  202.     local setPressed = false;
  203.     if key==42 or key==29 or key==56 then
  204.         if os.clock()-lastPressed[key] <= 0.3 then
  205.             keysPressed[key] = true;
  206.             lastPressed[key]=os.clock()+0.15;
  207.             setPressed=true;
  208.         end
  209.         lastPressed[key] = os.clock();
  210.     end
  211.     for i=1,3 do
  212.         local k = ({29,42,56})[i];
  213.         if not (key==42 or key==29 or key==56) or (k == key and not setPressed) then
  214.             keysPressed[k] = false
  215.         end
  216.     end
  217.     updateKeyDisplay();
  218.     if key==57 then
  219.         char=' ';
  220.     end
  221.     if key==58 then
  222.         capsLock=not capsLock;
  223.     end
  224.     return key, char;
  225. end
  226.  
  227. local function getMouseButton(x,y)
  228.     if y>= 20 and y<=22 and x > 32 and x <= ({36,38,37})[y-19] then
  229.         y = y-19;
  230.         if y ~= 1 then y=5-y end
  231.         return y;
  232.     end
  233.     return nil;
  234. end
  235.  
  236. local function setMouseButton(button)
  237.     colorSetup()
  238.     mouseButton=button;
  239.     monitor.setCursorPos(18,21)
  240.     monitor.write('Mouse button:')
  241.     for i=1,3 do
  242.         monitor.setCursorPos(32,19+i)
  243.         local char1 = (i==1 and 1 or 5-i)==button and '>' or ' '
  244.         local char2 = (i==1 and 1 or 5-i)==button and '<' or ' '
  245.         monitor.write(char1..({'Left','Middle','Right'})[i]..char2)
  246.     end
  247. end
  248. setMouseButton(1);
  249.  
  250. local function getScroll(x,y)
  251.     if y>=21 and y<=22 and x>=45 and x<=({46,48})[y-20] then
  252.         return (y-20)*2 - 3;
  253.     end
  254.     return nil
  255. end
  256.  
  257. --[[for i=1,4 do
  258.     monitor.setCursorPos(45,25+i)
  259.     monitor.write(({'Up','Left','Right','Down'})[i])
  260. end]]
  261. -- Main loop --
  262.  
  263. resume();
  264. local ok,err = pcall(function()
  265.     for event,p1,p2,p3,p4,p5 in os.pullEvent do
  266.         debug(event,': ',table.concat({p1,p2,p3,p4,p5},', '))
  267.         if event == 'monitor_touch' and p1 == side then
  268.             debug('Touched')
  269.             if p2 <= 51 and p3 <= 18 then
  270.                 resume('mouse_click', mouseButton, p2, p3)
  271.             else
  272.                 local key, char = getKey(p2, p3);
  273.                 if key and not filter or filter=='key' and not(char and ctrlPressed) then
  274.                     resume('key', key)
  275.                 end
  276.                 if char and not filter or filter=='char' then
  277.                     resume('char', char)
  278.                 end
  279.                 if not key then
  280.                     --[[local newButton = newMouseButton(p2,p3)
  281.                     if newButton then
  282.                         mouseButton = newButton;
  283.                     elseif
  284.                     end]]
  285.                     local button = getMouseButton(p2,p3);
  286.                     if button then
  287.                         setMouseButton(button)
  288.                     end
  289.                     local scroll = getScroll(p2,p3)
  290.                     if scroll then
  291.                         resume('mouse_scroll',scroll,1,1)
  292.                     end
  293.                 end
  294.             end
  295.         else
  296.             if not filter or filter==event then
  297.                 resume(event,p1,p2,p3,p4,p5)
  298.             end
  299.         end
  300.         if coroutine.status(program)=='dead' then
  301.             print('Program has exited')
  302.             break
  303.         end
  304.     end
  305. end)
  306. debug(err)
  307. colorSetup()
  308. monitor.clear()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement