...

Source file src/edge-infra.dev/pkg/sds/display/displaymanager/applier/xorg/command/xrandr/xrandr.go

Documentation: edge-infra.dev/pkg/sds/display/displaymanager/applier/xorg/command/xrandr

     1  package xrandr
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"slices"
     7  
     8  	"maps"
     9  
    10  	"edge-infra.dev/pkg/sds/display/displaymanager/applier/xorg/command"
    11  	"edge-infra.dev/pkg/sds/display/displaymanager/applier/xorg/command/runner"
    12  	"edge-infra.dev/pkg/sds/lib/xorg"
    13  )
    14  
    15  const xrandrPath = "/usr/bin/xrandr"
    16  
    17  const (
    18  	outputFlag  = "--output"
    19  	modeFlag    = "--mode"
    20  	rotateFlag  = "--rotate"
    21  	primaryFlag = "--primary"
    22  	posFlag     = "--pos"
    23  	rightOfFlag = "--right-of"
    24  )
    25  
    26  // Command is able to build an Xrandr command to configure displays and run it.
    27  type Command interface {
    28  	command.Command
    29  
    30  	SetOutputMode(outputID xorg.OutputID, mode string)
    31  	SetOutputRotation(outputID xorg.OutputID, rotation string)
    32  	SetOutputAsPrimary(outputID xorg.OutputID)
    33  	SetOutputPosition(outputID xorg.OutputID, xPos, yPos int)
    34  	SetOutputRightOf(outputID, relativeTo xorg.OutputID)
    35  }
    36  
    37  // NewXrandrCommand returns a new xrandr.Command implementation.
    38  func NewXrandrCommand(cmdRunner runner.Runner) Command {
    39  	return &xrandrCmd{
    40  		cmdRunner:   cmdRunner,
    41  		displayArgs: displayArgs{},
    42  	}
    43  }
    44  
    45  // Map of output IDs to the display's xrandr arguments
    46  type displayArgs map[xorg.OutputID][]string
    47  
    48  func (o displayArgs) Args() []string {
    49  	args := []string{}
    50  
    51  	// iterate over the sorted keys for consistent output
    52  	outputIDs := slices.Collect(maps.Keys(o))
    53  	slices.Sort(outputIDs)
    54  	for _, outputID := range outputIDs {
    55  		args = append(args, outputFlag)
    56  		args = append(args, outputID.String())
    57  		args = append(args, o[outputID]...)
    58  	}
    59  
    60  	return args
    61  }
    62  
    63  type xrandrCmd struct {
    64  	cmdRunner runner.Runner
    65  	displayArgs
    66  }
    67  
    68  func (x *xrandrCmd) Path() string {
    69  	return xrandrPath
    70  }
    71  
    72  func (x *xrandrCmd) Run() error {
    73  	if len(x.displayArgs) == 0 {
    74  		return nil
    75  	}
    76  	return x.cmdRunner.Run(xrandrPath, x.displayArgs.Args()...)
    77  }
    78  
    79  func (x *xrandrCmd) SetOutputMode(outputID xorg.OutputID, mode string) {
    80  	// e.g. --mode 1920x1080
    81  	x.displayArgs[outputID] = append(x.displayArgs[outputID], modeFlag, mode)
    82  }
    83  
    84  func (x *xrandrCmd) SetOutputRotation(outputID xorg.OutputID, rotation string) {
    85  	// e.g. --orientation normal
    86  	x.displayArgs[outputID] = append(x.displayArgs[outputID], rotateFlag, rotation)
    87  }
    88  
    89  func (x *xrandrCmd) SetOutputAsPrimary(outputID xorg.OutputID) {
    90  	// e.g. --primary
    91  	x.displayArgs[outputID] = append(x.displayArgs[outputID], primaryFlag)
    92  }
    93  
    94  func (x *xrandrCmd) SetOutputPosition(outputID xorg.OutputID, xPos, yPos int) {
    95  	// e.g. --pos 0x0
    96  	x.displayArgs[outputID] = append(x.displayArgs[outputID], posFlag, fmt.Sprintf("%dx%d", xPos, yPos))
    97  }
    98  
    99  func (x *xrandrCmd) SetOutputRightOf(outputID, relativeTo xorg.OutputID) {
   100  	// e.g. --right-of DP1
   101  	x.displayArgs[outputID] = append(x.displayArgs[outputID], rightOfFlag, relativeTo.String())
   102  }
   103  

View as plain text