Attachment 'vt_rotate-13.3-RELEASE.diff'
Download 1 diff --git a/share/man/man4/vt.4 b/share/man/man4/vt.4
2 index c75830bdd44f..f6ba0754fb3f 100644
3 --- a/share/man/man4/vt.4
4 +++ b/share/man/man4/vt.4
5 @@ -356,6 +356,24 @@ To set black and white colors of console palette
6 .Pp
7 .Dl kern.vt.color.0.rgb="10,10,10"
8 .Dl kern.vt.color.15.rgb="#f0f0f0"
9 +.Pp
10 +The mode option
11 +.Sy rotate
12 +is also supported, with values 0, 90, 180, and 270 representing the degrees
13 +counterclockwise to rotate the display. Follow an optional connector name
14 +and mode with a comma and the mode option. For example,
15 +to set the default rotation for all output connectors 90 degrees clockwise:
16 +.Pp
17 +.Dl kern.vt.fb.default_mode=",rotate=270"
18 +.Pp
19 +This option is only supported by
20 +.Cm vt_fb
21 +when it is paired with a KMS video driver, and in most cases the
22 +.Pp
23 +.Dl screen.rotate=90
24 +.Pp
25 +.Xr loader.conf 5
26 +setting, which will work with and without KMS, is more appropriate.
27 .Sh SEE ALSO
28 .Xr kbdcontrol 1 ,
29 .Xr login 1 ,
30 diff --git a/stand/defaults/loader.conf.5 b/stand/defaults/loader.conf.5
31 index bb40df0333cf..7c82dbd3c7f1 100644
32 --- a/stand/defaults/loader.conf.5
33 +++ b/stand/defaults/loader.conf.5
34 @@ -306,6 +306,16 @@ If EDID is not available, the default resolution is 800x600 (if available).
35 .Va screen.width ,
36 .Va screen.depth
37 are set by loader when loader is using framebuffer mode to draw the screen.
38 +.It Va screen.rotate
39 +Sets the rotation of the framebuffer console to 0, 90, 180, or 270 degrees clockwise.
40 +If KMS is present, the rotation may be performed in hardware,
41 +and an additional value, "AUTO", is supported which will often detect the
42 +correct rotation.
43 +.Pp
44 +This option will also rotate the screen of the EFI boot loader; because the rotation
45 +setting for the EFI loader is stored in the EFI itself during shutdown based upon the
46 +value present in the current kernel environment,
47 +it will take a second reboot to pass a change to the loader.
48 .It Va efi_max_resolution
49 .It Va vbe_max_resolution
50 Specify the maximum desired resolution for the EFI or VBE framebuffer console.
51 diff --git a/sys/dev/vt/hw/fb/vt_fb.c b/sys/dev/vt/hw/fb/vt_fb.c
52 index 96c54cfbe6ca..011aa1b3ebc4 100644
53 --- a/sys/dev/vt/hw/fb/vt_fb.c
54 +++ b/sys/dev/vt/hw/fb/vt_fb.c
55 @@ -160,11 +160,22 @@ vt_fb_setpixel(struct vt_device *vd, int x, int y, term_color_t color)
56 {
57 struct fb_info *info;
58 uint32_t c;
59 - u_int o;
60 + u_int o, row, col;
61
62 info = vd->vd_softc;
63 c = info->fb_cmap[color];
64 - o = info->fb_stride * y + x * FBTYPE_GET_BYTESPP(info);
65 +
66 + /* Rotations */
67 + if (info->fb_flags & FB_FLAG_ROTATE_90)
68 + row = x, col = y;
69 + else
70 + row = y, col = x;
71 + if (info->fb_flags & FB_FLAG_ROTATE_180)
72 + row = (info->fb_height - 1) - row;
73 + if (!(info->fb_flags & FB_FLAG_ROTATE_90) !=
74 + !(info->fb_flags & FB_FLAG_ROTATE_180))
75 + col = (info->fb_width - 1) - col;
76 + o = info->fb_stride * row + col * FBTYPE_GET_BYTESPP(info);
77
78 if (info->fb_flags & FB_FLAG_NOWRITE)
79 return;
80 @@ -264,7 +275,7 @@ vt_fb_bitblt_bitmap(struct vt_device *vd, const struct vt_window *vw,
81 unsigned int x, unsigned int y, term_color_t fg, term_color_t bg)
82 {
83 struct fb_info *info;
84 - uint32_t fgc, bgc, cc, o;
85 + uint32_t fgc, bgc, cc, o, row, col;
86 int bpp, bpl, xi, yi;
87 int bit, byte;
88
89 @@ -297,7 +308,18 @@ vt_fb_bitblt_bitmap(struct vt_device *vd, const struct vt_window *vw,
90 /* Skip pixel write, if mask bit not set. */
91 if (mask != NULL && (mask[byte] & bit) == 0)
92 continue;
93 - o = (y + yi) * info->fb_stride + (x + xi) * bpp;
94 +
95 + /* Rotations */
96 + if (info->fb_flags & FB_FLAG_ROTATE_90)
97 + row = x + xi, col = y + yi;
98 + else
99 + row = y + yi, col = x + xi;
100 + if (info->fb_flags & FB_FLAG_ROTATE_180)
101 + row = (info->fb_height - 1) - row;
102 + if (!(info->fb_flags & FB_FLAG_ROTATE_90) !=
103 + !(info->fb_flags & FB_FLAG_ROTATE_180))
104 + col = (info->fb_width - 1) - col;
105 + o = row * info->fb_stride + col * bpp;
106 o += vd->vd_transpose;
107 cc = pattern[byte] & bit ? fgc : bgc;
108
109 @@ -457,15 +479,64 @@ vt_fb_init(struct vt_device *vd)
110 {
111 struct fb_info *info;
112 u_int margin;
113 - int bg, err;
114 + int angle = 0, bg, err;
115 term_color_t c;
116 + char *rotation, strbuf[4];
117
118 info = vd->vd_softc;
119 - vd->vd_height = MIN(VT_FB_MAX_HEIGHT, info->fb_height);
120 - margin = (info->fb_height - vd->vd_height) >> 1;
121 - vd->vd_transpose = margin * info->fb_stride;
122 - vd->vd_width = MIN(VT_FB_MAX_WIDTH, info->fb_width);
123 - margin = (info->fb_width - vd->vd_width) >> 1;
124 +
125 + /*
126 + * If we have been passed a rotation, and screen.rotate="AUTO", change
127 + * screen.rotate to the autodetected rotation for use during the next
128 + * reboot.
129 + */
130 + if (info->fb_flags & FB_FLAG_ROTATE_NODEFAULT) {
131 + if ((rotation = kern_getenv("screen.rotate")) != NULL &&
132 + strncasecmp(rotation, "auto", 5) == 0) {
133 + if (info->fb_flags & FB_FLAG_ROTATE_90)
134 + angle += 90;
135 + if (info->fb_flags & FB_FLAG_ROTATE_180)
136 + angle += 180;
137 + snprintf(strbuf, sizeof(strbuf), "%d", angle);
138 + kern_setenv("screen.rotate", strbuf);
139 + }
140 + freeenv(rotation);
141 + }
142 +
143 + /* Default angle to rotate console clockwise, in 90 degree increments. */
144 + if (!(info->fb_flags & FB_FLAG_ROTATE_NODEFAULT)) {
145 + if ((TUNABLE_INT_FETCH("screen.autorotate", &angle) == 0))
146 + TUNABLE_INT_FETCH("screen.rotate", &angle);
147 + info->fb_flags &= ~FB_FLAG_ROTATE_MASK;
148 + switch (angle) {
149 + case 270:
150 + info->fb_flags |= FB_FLAG_ROTATE_270;
151 + break;
152 + case 180:
153 + info->fb_flags |= FB_FLAG_ROTATE_180;
154 + break;
155 + case 90:
156 + info->fb_flags |= FB_FLAG_ROTATE_90;
157 + break;
158 + default:
159 + info->fb_flags |= FB_FLAG_ROTATE_0;
160 + break;
161 + }
162 + }
163 +
164 + if (info->fb_flags & FB_FLAG_ROTATE_90) { /* +/-90 degrees rotation */
165 + vd->vd_height = MIN(VT_FB_MAX_HEIGHT, info->fb_width);
166 + vd->vd_width = MIN(VT_FB_MAX_WIDTH, info->fb_height);
167 + margin = (info->fb_height - vd->vd_width) >> 1;
168 + vd->vd_transpose = margin * info->fb_stride;
169 + margin = (info->fb_width - vd->vd_height) >> 1;
170 + } else {
171 + vd->vd_height = MIN(VT_FB_MAX_HEIGHT, info->fb_height);
172 + vd->vd_width = MIN(VT_FB_MAX_WIDTH, info->fb_width);
173 + margin = (info->fb_height - vd->vd_height) >> 1;
174 + vd->vd_transpose = margin * info->fb_stride;
175 + margin = (info->fb_width - vd->vd_width) >> 1;
176 + }
177 vd->vd_transpose += margin * (info->fb_bpp / NBBY);
178 vd->vd_video_dev = info->fb_video_dev;
179
180 diff --git a/sys/sys/fbio.h b/sys/sys/fbio.h
181 index 9123a2008b7a..d8e3e83d423b 100644
182 --- a/sys/sys/fbio.h
183 +++ b/sys/sys/fbio.h
184 @@ -141,9 +141,15 @@ struct fb_info {
185 void *fb_priv; /* First argument for read/write. */
186 const char *fb_name;
187 uint32_t fb_flags;
188 -#define FB_FLAG_NOMMAP 1 /* mmap unsupported. */
189 -#define FB_FLAG_NOWRITE 2 /* disable writes for the time being */
190 -#define FB_FLAG_MEMATTR 4 /* override memattr for mmap */
191 +#define FB_FLAG_NOMMAP 0x01 /* mmap unsupported. */
192 +#define FB_FLAG_NOWRITE 0x02 /* disable writes for the time being */
193 +#define FB_FLAG_MEMATTR 0x04 /* override memattr for mmap */
194 +#define FB_FLAG_ROTATE_0 0x00 /* rotate fb 0 degrees clockwise */
195 +#define FB_FLAG_ROTATE_90 0x08 /* rotate fb 90 degrees clockwise */
196 +#define FB_FLAG_ROTATE_180 0x10 /* rotate fb 180 degrees clockwise */
197 +#define FB_FLAG_ROTATE_270 (FB_FLAG_ROTATE_90 | FB_FLAG_ROTATE_180)
198 +#define FB_FLAG_ROTATE_MASK 0x18
199 +#define FB_FLAG_ROTATE_NODEFAULT 0x20 /* do not load console defaults */
200 vm_memattr_t fb_memattr;
201 int fb_stride;
202 int fb_bpp; /* bits per pixel */
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.