github.com/BurntSushi/xgb@v0.0.0-20210121224620-deaf085860bc/examples/randr/main.go (about)

     1  // Example randr uses the randr protocol to get information about the active
     2  // heads. It also listens for events that are sent when the head configuration
     3  // changes. Since it listens to events, you'll have to manually kill this
     4  // process when you're done (i.e., ctrl+c.)
     5  //
     6  // While this program is running, if you use 'xrandr' to reconfigure your
     7  // heads, you should see event information dumped to standard out.
     8  //
     9  // For more information, please see the RandR protocol spec:
    10  // http://www.x.org/releases/X11R7.6/doc/randrproto/randrproto.txt
    11  package main
    12  
    13  import (
    14  	"fmt"
    15  	"log"
    16  
    17  	"github.com/BurntSushi/xgb"
    18  	"github.com/BurntSushi/xgb/randr"
    19  	"github.com/BurntSushi/xgb/xproto"
    20  )
    21  
    22  func main() {
    23  	X, _ := xgb.NewConn()
    24  
    25  	// Every extension must be initialized before it can be used.
    26  	err := randr.Init(X)
    27  	if err != nil {
    28  		log.Fatal(err)
    29  	}
    30  
    31  	// Get the root window on the default screen.
    32  	root := xproto.Setup(X).DefaultScreen(X).Root
    33  
    34  	// Gets the current screen resources. Screen resources contains a list
    35  	// of names, crtcs, outputs and modes, among other things.
    36  	resources, err := randr.GetScreenResources(X, root).Reply()
    37  	if err != nil {
    38  		log.Fatal(err)
    39  	}
    40  
    41  	// Iterate through all of the outputs and show some of their info.
    42  	for _, output := range resources.Outputs {
    43  		info, err := randr.GetOutputInfo(X, output, 0).Reply()
    44  		if err != nil {
    45  			log.Fatal(err)
    46  		}
    47  
    48  		if info.Connection == randr.ConnectionConnected {
    49  			bestMode := info.Modes[0]
    50  			for _, mode := range resources.Modes {
    51  				if mode.Id == uint32(bestMode) {
    52  					fmt.Printf("Width: %d, Height: %d\n",
    53  						mode.Width, mode.Height)
    54  				}
    55  			}
    56  		}
    57  	}
    58  
    59  	fmt.Println("\n")
    60  
    61  	// Iterate through all of the crtcs and show some of their info.
    62  	for _, crtc := range resources.Crtcs {
    63  		info, err := randr.GetCrtcInfo(X, crtc, 0).Reply()
    64  		if err != nil {
    65  			log.Fatal(err)
    66  		}
    67  		fmt.Printf("X: %d, Y: %d, Width: %d, Height: %d\n",
    68  			info.X, info.Y, info.Width, info.Height)
    69  	}
    70  
    71  	// Tell RandR to send us events. (I think these are all of them, as of 1.3.)
    72  	err = randr.SelectInputChecked(X, root,
    73  		randr.NotifyMaskScreenChange|
    74  			randr.NotifyMaskCrtcChange|
    75  			randr.NotifyMaskOutputChange|
    76  			randr.NotifyMaskOutputProperty).Check()
    77  	if err != nil {
    78  		log.Fatal(err)
    79  	}
    80  
    81  	// Listen to events and just dump them to standard out.
    82  	// A more involved approach will have to read the 'U' field of
    83  	// RandrNotifyEvent, which is a union (really a struct) of type
    84  	// RanrNotifyDataUnion.
    85  	for {
    86  		ev, err := X.WaitForEvent()
    87  		if err != nil {
    88  			log.Fatal(err)
    89  		}
    90  		fmt.Println(ev)
    91  	}
    92  }