Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal
  • 0
Tomeado

Multi screen/screen mirroring

Question

Hello all! I have a question about how to go about connecting more than one monitor to a computer, mirroring the image or program to all monitors while still being able to interact with it on each monitor? Unfortunately I have mediocre python experience and no lua or Linux experience so I apologize ahead of time for any lack of understanding!

Link to post
Share on other sites

2 answers to this question

Recommended Posts

  • 0

Hey!

It is not that hard to run a program on multiple screens and being able to interact with all monitors. If you want to have the terminal on multiple screens you could modify the modules and then restart the computer, but there might be a better solution than this.

One gpu can only be bound to one screen, so you could basically write a lib that will redirect any gpu call to a function that iterates through all screens, binding the gpu and call the function for every screen.

Instead of doing this by hand for every function, we're going to use metatables (if you don't know about metatables, you should definitely check them out, they are a really powerful tool in Lua). 

Basically metatables allow you to change the way how objects behave in different situations, for example when exposed to an arithmetic or relational operator (this way you can tell Lua how to add 2 tables, check for equality etc; in regular Lua, you can also change the metatables of strings, but opencomputers removes that ability). The most powerful meta methods are __index and __newindex. They are triggered when you look up (or modify) an absent key. Instead of returning nil, if present, these meta methods are invoked. 

The __index meta method is what we're going to use for the implementation. We create a proxy table for the gpu, that will then return a function to iterate over all the screens.

local component = require'component'
local gpu = component.gpu


-- # create table containing all screens
local screens = component.list('screen')

-- # instead of invoking 'component.list' every time we make a gpu call
-- # we just update the list whenever a screen is added or removed
local function updatescreens(event, addr, ctype)
  if ctype ~= 'screen' then return nil end
  if event == 'component_added' then
    screens[addr] = 'screen'
  else
    screens[addr] = nil
  end
end

-- # listening to component adding or removing events, invoking 'updatescreen' on event
require'event'.listen('component_added', updatescreens)
require'event'.listen('component_removed', updatescreens)

-- # creating proxy table for gpu calls
local vgpu = {}
-- # making vgpu its own metatable
setmetatable(vgpu, vgpu)

-- # would not make sense to call 'bind' for every screen
vgpu.bind = gpu.bind

-- # '__index' function
function vgpu.__index(self, key)
  -- # since some gpu methods return some data, we differentiate between 'setter' and 'getter' methods
  -- # most setter function have 'set' in their name, 'fill' and 'copy' are the exception 
  local setter = { copy = true; fill = true}
  if key:find('set') or setter[key] then
    -- # function that will only call the methods, does not return anything (for setters)
    return function(...)
      for addr in pairs(screens) do
        self.bind(addr)
        gpu[key](...)
      end
    end
  else
    -- # function that will return data (for getters)
    -- # returns table with screen address as key and table or single object as value
    -- # {'addr 1' = value1, 'addr 2' = value2, ...}
    return function(...)
      local res = {}
      for addr in pairs(screens) do
        self.bind(addr)
        local r = {gpu[key](...)}
        res[addr] = #r == 1 and r[1] or r
      end
      return res
    end
  end
end

-- returns gpu proxy, so it can be used as a module
return vgpu

If you have a keyboard attached to all screens, you are able to interact with all of them using a basic event handler.

If you have any further questions, feel free to ask:)

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.