main 5d6fa26

dumb.go RawHistoryFolder

1package drm
2
3import (
4	"errors"
5	"fmt"
6	"unsafe"
7
8	"golang.org/x/sys/unix"
9)
10
11// KMS dumb buffers: the driver allocates a linear buffer the CPU maps and
12// the display scans out. Cursor images use them (see cursor_images.go).
13
14const (
15	ioctlCreateDumb  = 0xC02064B2 // DRM_IOWR('d', 0xB2, struct drm_mode_create_dumb)
16	ioctlMapDumb     = 0xC01064B3 // DRM_IOWR('d', 0xB3, struct drm_mode_map_dumb)
17	ioctlDestroyDumb = 0xC00464B4 // DRM_IOWR('d', 0xB4, struct drm_mode_destroy_dumb)
18)
19
20type createDumb struct {
21	height, width, bpp, flags uint32
22	handle, pitch             uint32
23	size                      uint64
24}
25
26type mapDumb struct {
27	handle, pad uint32
28	offset      uint64
29}
30
31// dumbBuffer is a dumb buffer's GEM handle, row pitch and size in bytes.
32type dumbBuffer struct {
33	handle, pitch uint32
34	size          uint64
35}
36
37func (k kmsDevice) createDumb(width, height int) (dumbBuffer, error) {
38	if width <= 0 || height <= 0 {
39		return dumbBuffer{}, fmt.Errorf("dumb buffer size %dx%d", width, height)
40	}
41	c := createDumb{height: uint32(height), width: uint32(width), bpp: 32}
42	if err := ioctl(k.fd, ioctlCreateDumb, unsafe.Pointer(&c)); err != nil {
43		return dumbBuffer{}, err
44	}
45	return dumbBuffer{handle: c.handle, pitch: c.pitch, size: c.size}, nil
46}
47
48func (k kmsDevice) mapDumb(b dumbBuffer) ([]byte, error) {
49	m := mapDumb{handle: b.handle}
50	if err := ioctl(k.fd, ioctlMapDumb, unsafe.Pointer(&m)); err != nil {
51		return nil, err
52	}
53	if b.size == 0 || b.size > 1<<30 {
54		return nil, fmt.Errorf("dumb buffer size %d", b.size)
55	}
56	return unix.Mmap(k.fd, int64(m.offset), int(b.size), unix.PROT_READ|unix.PROT_WRITE, unix.MAP_SHARED)
57}
58
59func (k kmsDevice) unmapDumb(mem []byte) error { return unix.Munmap(mem) }
60
61// addFBHandle makes a framebuffer of format over the dumb buffer, without
62// modifier (the driver's linear layout).
63func (k kmsDevice) addFBHandle(b dumbBuffer, width, height int, format uint32) (uint32, error) {
64	if b.handle == 0 {
65		return 0, errors.New("no dumb buffer")
66	}
67	cmd := fbCmd2{width: uint32(width), height: uint32(height), format: format}
68	cmd.handles[0], cmd.pitches[0] = b.handle, b.pitch
69	if err := ioctl(k.fd, ioctlAddFB2, unsafe.Pointer(&cmd)); err != nil {
70		return 0, errors.Join(errors.New("add fb2"), err)
71	}
72	return cmd.fbID, nil
73}
74
75func (k kmsDevice) destroyDumb(handle uint32) error {
76	return ioctl(k.fd, ioctlDestroyDumb, unsafe.Pointer(&handle))
77}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 23

Tags 10

↑↓ moveenter openesc close