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

Archived

This topic is now archived and is closed to further replies.

  • 0
joserobjr

How do I print to a second monitor?

Question

I've been trying and searching about it without success...

I have a computer with 2 GPUs and 2 screens, I'm trying to use the primary GPU and screen to render a GUI and the second pair to show the application log.

I also tried to copy the term lib in attempt to have a parallel term, but term2.write still writes to the main screen...

This is what I have so far:

local term2

local primaryGpu = component.gpu
local primaryScreen = component.screen
---@type component.gpu
local secondaryGpu
---@type component.screen
local secondaryScreen

for gpuAddr in pairs(component.list("gpu")) do
    if not component.isPrimary(gpuAddr) then
        for screenAddr in pairs(component.list("screen")) do
            if not component.isPrimary(screenAddr) then
                ---@type component.gpu
                local gpu = component.proxy(gpuAddr)
                ---@type component.screen
                local screen = component.proxy(screenAddr)
                screen.turnOn()
                gpu.bind(screenAddr, true)
                beep()
                secondaryGpu = gpuAddr
                secondaryScreen = screenAddr

                component.setPrimary("gpu", secondaryGpu)
                component.setPrimary("screen", secondaryScreen)
                print("Second monitor?")
                component.setPrimary("gpu", primaryGpu)
                component.setPrimary("screen", primaryScreen)

                --[[term2 = require("copied_term")
                term2.bind(gpu, screen)
                term2.setCursor(1,1)
                term2.setCursorBlink(true)
                term2.clear()
                term2.write("Screen loaded. Uptime: "..uptime())
                ]]--
            end
        end
    end
end

 

Do you have any idea?

Share this post


Link to post
Share on other sites

3 answers to this question

Recommended Posts

The documentation for the term library is incorrect with respect to the latest version of OpenOS. Basically the term library will use whichever screen is bound to the tty output. Its a bit confusing personally. I would recommend reading through the term and tty library to see how they are related. But, to answer your question you can use this..

local component = require "component"
local term = require 'term'
local thread = require 'thread'
local fs = require 'filesystem'

local function getSecondary(ctype)
    local path = '/dev/components/by-type/' .. ctype .. '/1'
    if fs.exists(path) then
        local file = assert(fs.open(path .. '/address', 'r'), 'failed to open ' .. path .. '/address.')
        local address = file:read()
        file:close()
        return address
    end
    return nil, 'no secondary ' .. ctype .. ' component.'
end

local gpu2 = component.proxy(getSecondary('gpu'))
gpu2.bind(getSecondary('screen'))

local function Window(dx, dy, w, h, gpu)
    gpu = gpu or term.gpu()
    local window = term.internal.open(dx, dy, w, h)
    term.bind(gpu, window)
    window.as_window = term.internal.run_in_window
    return window
end

local window = Window(0, 0, 160, 50, gpu2) -- # give window offset & dimensions and gpu proxy.
local function log(...)
    return window:as_window(print, ...) -- # run print with the tty window as our our window
end

print "This is on the main screen"
log "This is on the second screen"

hope this is helpful..

Some thing else fun to try and use as well..

-- # considering the above code..
-- # take term char input on two screens at once

thread.create(function()
    	window:as_window( term.read ) -- # read input on term 2. blink and all :)
    end)

-- # the windowed term.read will exit either when it returns or if this call returns first closing the above thread.
term.read() -- # read from main term input.

 

Share this post


Link to post
Share on other sites

This post gives me a few things to think about

First - @Molinko what is wrong about the documentation and the term library? I have a ticket on github to clean up the docs and I do plan to give the term doc page another review. But are there things specifically that you know to be wrong or confusing? If you do, please add your feedback to the github ticket: https://github.com/MightyPirates/OpenComputers/issues/2686

Second - I should have known that even if I put things in an `internal` sub table, people would still use them. Feel free to use the `term.internal.open` and `term.internal.run_in_window`, but you should also know these are not api - and can change without warning. They've now been around for a long time, but I may refactor them later.

Third - OpenOS does not have multiple window support. Our internal (again, internal) structures have future support built in to support multiple windows, but we do not have an API for this yet. Thus, the solution you build is going to feel a bit complex or hacked, and you'll likely be making internal calls. Because again, this is not officially supported.

The idea is this: term doesn't bind to a gpu, and tty doesn't bind to a gpu, the PROCESS is bound to a gpu. And the gpu is bound to a window. Child processes inherit their parent gpu and such. The internal workings of how this happens (in the term lib and in the tty lib) should not affect your user code. If you want to switch between screens, rebind the gpu. If you want to leave a gpu bound to a screen, and switch between gpus, then set the term gpu between the two. But I understand that this doesn't work with cursor positions and input buffers

Fourth - @Molinko holy crap, someone is using the devfs! Ha! I'm pretty excited by that :) nice. And yes, you have the code correct. The first ( /0 ) will be the primary.

Fifth - @joserobjr Changing the component primary device will not affect the kernel in any way. That only affects user code that is using the convenience method on the `component` library for quick access to the primary component of a type: `component[type]` In other words, for example changing the primary gpu changes the object returned by `component.gpu` but the kernel does not use this anywhere

Share this post


Link to post
Share on other sites

@payonel Howdy! About the term lib documentation; I was specifically referring to the doc for term.bind. The optional [screen & keyboard] parameters suggested in the doc dont seem to have an actual implementation in the current OpenOS( although at the time of this response i havent bothered to double check that. Just referring to previous hair pulling encounters ). Ill add a ticket tomorrow if I dont totally space.

You did warn me about messing with anything under the .internal space of an OpenOS lib, but I like dancing on sharp edges :P . Love what you're doing with the place too! (OpenOS)

Third. Yup. I want a full tty pty abstraction layer for programs but after looking into how to pull it off myself I figured I'd wait for you to do it :P , lol.

8 hours ago, payonel said:

The idea is this: term doesn't bind to a gpu, and tty doesn't bind to a gpu, the PROCESS is bound to a gpu.

This is definitely illuminating for me as, for me at least, this wasn't straight forward to grok just peeping the source. Thanks for that. OpenOS is my first use of any linux like OS arch and I'm learning a lot.

I really like the dev system. I want to learn to exploit it a lot more. That example is actually the first use i've personally thought of for it and that only happened because looping several type of components and binding screens, gpus, and keyboards can be quite tedious :) .

Thanks for the input. Always a pleasure.

Share this post


Link to post
Share on other sites

×
×
  • Create New...

Important Information

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