Video display modes: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added Wren)
Line 720: Line 720:


With modern LCD monitors, this feature is not very useful. These monitors have a single best mode, and the X server discovers and uses that mode by default. Smaller screen modes might work, but make a blurry picture.
With modern LCD monitors, this feature is not very useful. These monitors have a single best mode, and the X server discovers and uses that mode by default. Smaller screen modes might work, but make a blurry picture.

=={{header|Wren}}==
The ability to call external processes such as ''xrandr'' is expected to be added to Wren-cli in the next release. In the meantime, we embed the following Wren script in a minimal C host (no error checking) to complete this task.
<lang ecmascript>/* video_display_modes.wren */

class C {
foreign static xrandr(args)

foreign static usleep(usec)
}

// query supported display modes
C.xrandr("-q")

C.usleep(3000)

// change display mode to 1368x768
System.print("\nChanging to 1368 x 768 mode.")
C.xrandr("-s 1368x768")

C.usleep(3000)

// change it back again to 1920x1080
System.print("\nReverting to 1920 x 1080 mode.")
C.xrandr("-s 1920x1080")</lang>
<br>
We now embed this in the following C program, compile and run it.
<lang c>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "wren.h"

void C_xrandr(WrenVM* vm) {
const char *arg = wrenGetSlotString(vm, 1);
char command[strlen(arg) + 8];
strcpy(command, "xrandr ");
strcat(command, arg);
system(command);
}

void C_usleep(WrenVM* vm) {
useconds_t usec = (useconds_t)wrenGetSlotDouble(vm, 1);
usleep(usec);
}

WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "C") == 0) {
if (isStatic && strcmp(signature, "xrandr(_)") == 0) return C_xrandr;
if (isStatic && strcmp(signature, "usleep(_)") == 0) return C_usleep;
}
}
return NULL;
}

static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}

char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
fread(script, 1, fsize, f);
fclose(f);
script[fsize] = 0;
return script;
}

int main(int argc, char **argv) {
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.bindForeignMethodFn = &bindForeignMethod;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "video_display_modes.wren";
char *script = readFile(fileName);
wrenInterpret(vm, module, script);
wrenFreeVM(vm);
free(script);
return 0;
}</lang>

{{out}}
<pre>
Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 16384 x 16384
eDP-1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 344mm x 193mm
1920x1080 60.01*+ 60.01 59.97 59.96 59.93
1680x1050 59.95 59.88
1600x1024 60.17
1400x1050 59.98
1600x900 59.99 59.94 59.95 59.82
1280x1024 60.02
1440x900 59.89
1400x900 59.96 59.88
1280x960 60.00
1440x810 60.00 59.97
1368x768 59.88 59.85
1360x768 59.80 59.96
1280x800 59.99 59.97 59.81 59.91
1152x864 60.00
1280x720 60.00 59.99 59.86 59.74
1024x768 60.04 60.00
960x720 60.00
928x696 60.05
896x672 60.01
1024x576 59.95 59.96 59.90 59.82
960x600 59.93 60.00
960x540 59.96 59.99 59.63 59.82
800x600 60.00 60.32 56.25
840x525 60.01 59.88
864x486 59.92 59.57
800x512 60.17
700x525 59.98
800x450 59.95 59.82
640x512 60.02
720x450 59.89
700x450 59.96 59.88
640x480 60.00 59.94
720x405 59.51 58.99
684x384 59.88 59.85
680x384 59.80 59.96
640x400 59.88 59.98
576x432 60.06
640x360 59.86 59.83 59.84 59.32
512x384 60.00
512x288 60.00 59.92
480x270 59.63 59.82
400x300 60.32 56.34
432x243 59.92 59.57
320x240 60.05
360x202 59.51 59.13
320x180 59.84 59.32
DP-1 disconnected (normal left inverted right x axis y axis)
HDMI-1 disconnected (normal left inverted right x axis y axis)
HDMI-2 disconnected (normal left inverted right x axis y axis)

Changing to 1368 x 768 mode.

Reverting to 1920 x 1080 mode.
</pre>


=={{header|XPL0}}==
=={{header|XPL0}}==

Revision as of 10:21, 24 September 2021

Task
Video display modes
You are encouraged to solve this task according to the task description, using any language you may know.

The task is to demonstrate how to switch video display modes within the language. A brief description of the supported video modes would be useful.

AmigaBASIC

<lang amigabasic>SCREEN 1,320,200,5,1</lang> This command creates a new screen #1 (4 max) with 320x200 pixels and 5 bits per pixel (for a total of 2⁵=32 colors). The final parameter, 1, sets the monitor to 320x200 (NTSC Amiga) or 320x256 (PAL Amiga) non-interlaced mode. If set to 2, it would use 640*200/640*256, while 3 and 4 would result in corresponding interlaced modes with twice the vertical resolution.

The screen can be closed again with <lang amigabasic>SCREEN CLOSE 1</lang>

Applesoft BASIC

There are ten possible modes:

TEXT, page 1, 40 x 24
GR, page 1, 40 x 40, 16 colors, mixed with four lines of text
HGR, page 1, 280 x 160, 6 colors, mixed with four lines of text
HGR2, page 2, 280 x 192, 6 colors, full screen
text, page 2, 40 x 24
gr, page 1, 40 x 48, 16 colors, full screen
gr, page 2, 40 x 40, 16 colors, mixed with four lines of text 
gr, page 2, 40 x 48, 16 colors, full screen
hgr, page 1, 280 x 192, 6 colors, full screen
hgr, page 2, 280 x 160, 6 colors, mixed with four lines of text

<lang ApplesoftBasic>10 GR 20 FOR I = 0 TO 15 : COLOR = I : PLOT I,I : NEXT 30 HGR 40 FOR I = 1 TO 6 : HCOLOR = I : HPLOT I * 2, I TO I * 2 + 1, I : NEXT 50 TEXT 60 HOME : FOR I = 0 TO 7 : VTAB I + 1 : FOR J = 0 TO 31 : POKE PEEK(40) + PEEK(41) * 256 + 4 + J, I * 32 + J : NEXT J, I 70 HGR2 80 FOR I = 1 TO 6 : HCOLOR = I : HPLOT I * 2, I + 6 TO I * 2 + 1, I + 6 : NEXT 90 TEXT 100 GET A$ 110 IF A$ = "H" THEN POKE -16297,0 : REM HI-RESOLUTION 120 IF A$ = "L" THEN POKE -16298,0 : REM LO-RESOLUTION 130 IF A$ = "2" THEN POKE -16299,0 : REM PAGE 2 140 IF A$ = "1" THEN POKE -16300,0 : REM PAGE 1 150 IF A$ = "M" THEN POKE -16301,0 : REM MIXED TEXT 160 IF A$ = "F" THEN POKE -16302,0 : REM FULL SCREEN 170 IF A$ = "T" THEN POKE -16303,0 : REM TEXT 180 IF A$ = "G" THEN POKE -16304,0 : REM GRAPHICS 190 IF A$ <> "Q" THEN 100 200 TEXT</lang>

ARM Assembly

Game Boy Advance

[Game Boy Advance Specifications]

The video display mode is a 16 bit value that is written to address 0x04000000. The lowest 3 bits control the screen mode. There are 5 to choose from. Modes 0-1 use tile graphics, Mode 2 is similar to the famous "Mode 7" on the SNES, and Modes 3, 4, and 5 are bitmap modes much like 80s home computers where individual pixels can be edited. Visibility of the background layers are controlled by bits 8 through 12 (going from right to left).

For example, to set the screen to Mode 3 with Background 2 visible: <lang ARM Assembly> MOV R1,#0x04000000 MOV R0,#0x403 STR r0,[r1] ;the game boy advance is little-endian, so I would have expected this not to work. However it does indeed work. </lang>

BBC BASIC

<lang bbcbasic>10 MODE 1: REM 320x256 4 colour graphics</lang>

Commodore BASIC

Commodore 64

Since BASIC V2 on the Commodore 64 has no specific commands to operate the graphics functions of the VIC-II, video modes must be activated by directly manipulating the various registers of the VIC-II chip. Also, no initialization is done of any user-programmable graphics memory at start up, as it is not known at startup what memory locations will be utilized for graphics. It is up to the user to decide how to utilize the memory and then make the appropriate initialization.


Summary of Video Modes

  • Standard Character Mode
    • 40 x 25 characters.
    • Single foreground color per character.
    • 16 colors available for use.
    • Font data comes from ROM.
  • Multicolor Character Mode
    • 40 x 25 characters.
    • Characters are either single colored or multi-colored.
    • Multi-color allows for 3 foreground colors per character.
    • 1 foreground color limited to first 8 colors of the palette; other 2 are global for entire screen, but may be any of 16 colors.
  • Extended Color Mode
    • Enables a total of 4 background colors which can be any of the 16 palette colors.
    • Limits character set to only first 64 characters (no PETSCII graphics or reverse characters.)
  • Programmable Character Mode
    • Works with any of the modes described above.
    • Exception is that font data comes from data in RAM.
  • Standard High Resolution Bit Mapped Mode
    • 320 x 200 pixel resolution.
    • Single foreground color per 8x8 pixel cell.
    • Single background color per 8x8 pixel cell.
    • Foreground and background color can be any of the 16 color palette.
    • Color information stored in character screen RAM, not color RAM.
  • Multicolor Hi-res Bit Mapped Mode
    • 160 x 200 pixel resolution.
    • Each 4x8 cell can have 3 foreground colors and 1 global background color.
    • Color information for foreground colors is stored in character screen RAM as well as color RAM (12 bits of color information).


Explanation of Program

Lines Description
10-25 Clear the screen, switch to lower-case mode, set the basic border, background, and foreground colors, including the extended and multicolors.
30 Check to see if we've run this routine before by examining the first two bytes of our reserved graphics area. If we have, skip it. (It does take some time to complete.)
35 Tell BASIC to limit its RAM usage to a new top-end of 8K. The following 8K (8192 to 16384) will be reserved for graphics data to be used by the VIC-II.
40 Let the user know we're initializing.
45 The contents of the character ROM are not normally visible to the CPU and must be switched through the I/O port of the CPU. However, this will also make certain interrupt functions running in the background fail, so interrupts must be turned off by stopping the interrupt timer on CIA 2 (first POKE in line 45) before switching the ROM in (second POKE in line 45).
50 Initialize part of the graphics area by copying all 4K of character ROM into the reserved graphics area.
55 Switch out the ROM since we are done with it, and restart the interrupt timer.
60-115 Modify a few characters to be custom designed (defined in DATA statements), and then define the rest of the reserved graphics memory with high-resolution lines (line 65), as well as a specific bit pattern that will help illustrate the high resolution multi-color mode (line 70).
480-810 This section goes through each of the modes. Activation of the modes is called as a subroutine, and some video modes are actually a combination of discrete video modes.
1000-1020 A subroutine to print some demonstration text to the screen to illustrate the variety of the various text modes. On lines 1011 and 1013, chr$(160) is the same as SHIFT-SPACE for the spaces between letters, which is distinctly different from a regular SPACE character (CHR$(32)).
1050-1065 A subroutine to put a variety of color definition into the high-resolution bit map modes.
1100-1430 These subroutines are the methods for switching certain discrete video modes on and off. This is done by specifically modifying the various registers in the VIC-II chip. Most of these are then combined to achieve other video modes.
9000-9020 Finally, a generic "wait for keypress" routine.


Program Listing

<lang gwbasic>10 rem video modes - c64 15 rem rosetta code 20 print chr$(147);chr$(14):poke 53280,0:poke 53281,0:poke 646,1 25 poke 53282,2:poke 53283,11:poke 53284,9:rem set extended and multi colors 30 if peek(12288)=60 and peek(12289)=102 then goto 100 35 poke 52,32:poke 56,32:clr 40 print "Initializing - Please wait..." 45 poke 56334,peek(56334) and 254:poke1,peek(1) and 251 50 for i=0 to 4096:poke i+12288,peek(i+53248):next 55 poke1,peek(1) or 4:poke56334,peek(56334) or 1 60 for i=0 to 31:read d:poke 15368+i,d:next i 65 x=0:for i=8192 to 10239:poke i,2^x:x=(x+1) and 7:next 70 for i=10240 to 12287:poke i,228:next 100 data 60,66,165,129,165,153,66,60 105 data 60,66,165,129,153,165,66,60 110 data 245,245,245,245,10,10,10,10 115 data 10,10,10,10,245,245,245,245 480 print chr$(147);"Demonstration of Video Modes" 485 print 490 print "The video modes described at Rosetta " 495 print "Code will be demonstrated in order. " 500 print "Simply press a key to advance to the" 505 print "next video mode." 510 print 515 print "See rosettacode.org for description." 516 print 517 print "http://www.rosettacode.org/wiki/"; 518 print "Video";chr$(164);"display";chr$(164);"modes#"; 519 print "Commodore";chr$(164);"BASIC" 520 print 525 print "Press any key to begin." 530 gosub 9010 600 print chr$(147);"Standard Character Mode" 605 print " - ROM Characters" 610 print:gosub 1000:print:gosub 9000:print chr$(147) 615 gosub 1210 620 print chr$(147);"Multicolor Character Mode" 625 print " - ROM Characters" 630 print:gosub 1000:print:gosub 9000:print chr$(147) 635 gosub 1220 640 gosub 1310 645 print chr$(147);"Extended Color Character Mode" 650 print " - ROM Characters" 655 print:gosub 1000:print:gosub 9000:print chr$(147) 660 gosub 1320 665 gosub 1100 670 print chr$(147);"Standard Character Mode" 675 print " - Programmed Characters" 680 print:gosub 1000:print:gosub 9000:print chr$(147) 685 gosub 1210 690 print chr$(147);"Multicolor Character Mode" 695 print " - Programmed Characters" 700 print:gosub 1000:print:gosub 9000:print chr$(147) 705 gosub 1220 710 gosub 1310 715 print chr$(147);"Extended Color Character Mode" 720 print " - Programmed Characters" 725 print:gosub 1000:print:gosub 9000:print chr$(147) 730 gosub 1320 735 print chr$(147);"The next screen will be the" 740 print "High Resolution Bit Map Mode" 745 print 750 gosub 9000 755 gosub 1430:gosub 1410 760 print:gosub 1050:print:gosub 9010:print chr$(147) 765 gosub 1420:gosub 1120 770 print chr$(147);"The next screen will be the" 775 print "Multicolor High Resolution Bit Map Mode" 780 print 785 gosub 9000 790 gosub 1430:gosub 1410:gosub 1210 795 print:gosub 1050:print:gosub 9010:print chr$(147) 800 gosub 1420:gosub 1220:gosub 1120 805 print chr$(147);"End of demonstration." 810 end 1000 rem put some characters up for demo 1005 for i=0 to 15:poke 646,i 1010 print" a b c d "; 1011 print chr$(160);"A";chr$(160);"B";chr$(160);"C";chr$(160);"D";chr$(160); 1012 print chr$(18);" a b c d "; 1013 print chr$(160);"A";chr$(160);"B";chr$(160);"C";chr$(160);"D";chr$(160); 1014 print chr$(146) 1015 next i:poke 646,1 1020 return 1050 rem show color variety for hi-res modes 1051 print chr$(147) 1055 for i=0 to 255:poke 1024+i,i:poke 55296+i,1:next 1060 for i=0 to 255:poke 1280+i,i:poke 55552+i,int(rnd(1)*16):next 1065 return 1100 rem programmable character mode 1110 poke 53272,(peek(53272) and 240)+14:return:rem on 1120 poke 53272,(peek(53272) and 240)+6:return:rem off 1200 rem multicolor mode 1210 poke 53270,peek(53270) or 16:return:rem on 1220 poke 53270,peek(53270) and 239:return:rem off 1300 rem extended color mode 1310 poke 53265,peek(53265) or 64:return:rem on 1320 poke 53265,peek(53265) and 191:return:rem off 1400 rem hi res mode 1410 poke 53265,(peek(53265) or 32):return:rem on 1420 poke 53265,(peek(53265) and 223):return:rem off 1430 poke 53272,peek(53272) or 8:return:rem place bitmap at 8192 9000 print "Press any key for next screen."; 9010 get k$:if k$="" then 9010 9020 return</lang>

ERRE

ERRE language (for PC) supports these modes (accessible with SCREEN procedure of PC.LIB library):

  • SCREEN(0) => text 80x25 or 40x25 -- standard
  • SCREEN(1) => 320x200 4 colors
  • SCREEN(2) => 640x200 2 colors
  • SCREEN(7) => 320x200 16 colors
  • SCREEN(8) => 640x200 16 colors
  • SCREEN(9) => 640x350 16 colors
  • SCREEN(10) => 640x350 for MDA monitors (if you have one .....)

It's possible to activate all VGA and SVGA modes using DOS interrupts. On the distribution disk there is an example to activate 320x200 - 256 colors.

ERRE language (for C-64) support high resolution graphic (320x200) using HGR.LIB library.

Go

Translation of: UNIX Shell
Works with: Ubuntu 16.04

<lang go>package main

import (

   "fmt"
   "log"
   "os/exec"
   "time"

)

func main() {

   // query supported display modes
   out, err := exec.Command("xrandr", "-q").Output()
   if err != nil {
       log.Fatal(err)
   }
   fmt.Println(string(out))
   time.Sleep(3 * time.Second)
   // change display mode to 1024x768 say (no text output)
   err = exec.Command("xrandr", "-s", "1024x768").Run()
   if err != nil {
       log.Fatal(err)
   }
   time.Sleep(3 * time.Second)
   // change it back again to 1366x768 (or whatever is optimal for your system)
   err = exec.Command("xrandr", "-s", "1366x768").Run()
   if err != nil {
       log.Fatal(err)
   }

}</lang>

Output:
Screen 0: minimum 8 x 8, current 1366 x 768, maximum 32767 x 32767
eDP1 connected primary 1366x768+0+0 (normal left inverted right x axis y axis) 344mm x 193mm
   1366x768      60.00*+  48.01  
   1360x768      59.80    59.96  
   1280x720      60.00  
   1024x768      60.00  
   1024x576      60.00  
   960x540       60.00  
   800x600       60.32    56.25  
   864x486       60.00  
   640x480       59.94  
   720x405       60.00  
   680x384       60.00  
   640x360       60.00  
DP1 disconnected (normal left inverted right x axis y axis)
DP2 disconnected (normal left inverted right x axis y axis)
HDMI1 disconnected (normal left inverted right x axis y axis)
HDMI2 disconnected (normal left inverted right x axis y axis)
VIRTUAL1 disconnected (normal left inverted right x axis y axis)

Groovy

Translation of: Kotlin
Works with: Ubuntu 14.04

<lang groovy>def invoke(String cmd) { println(cmd.execute().text) }

invoke("xrandr -q") Thread.sleep(3000)

invoke("xrandr -s 1024x768") Thread.sleep(3000)

invoke("xrandr -s 1366x768")</lang>

Output:
Screen 0: minimum 640 x 480, current 5080 x 1898, maximum 5080 x 1920
default connected 5080x1898+0+0 0mm x 0mm
   2880x1800     60.00  
   1440x900      60.00  
   2560x1600     60.00  
   2048x1280     60.00  
   1024x768      60.00  
   800x600       60.00  
   640x480       60.00  
   1680x1050     60.00  
   1280x800      60.00  
   5080x1898      1.00* 
   5080x1920      2.00  

GW-BASIC

This example is wrong! GWBASIC can use ONLY EGA-Graphic until SCREEN 9 (640 x 350 - 16 colors) with color monitor or SCREEN 10 (640 x 350 - 2 "colors") for monochrome monitor. GWBASIC version used: 3.23

<lang gwbasic>10 REM GW Basic can switch VGA modes 20 SCREEN 18: REM Mode 12h 640x480 16 colour graphics</lang>

Icon and Unicon

The following works in both languages on X-windows based systems and assume xrandr is installed:

Translation of: UNIX Shell

<lang unicon>procedure main(A)

   mode := A[1]
   if \mode then system("xrandr -s " || \mode || " >/dev/null")
   else system("xrandr -q")    # Display available modes

end</lang>

Output with no arguments:

->vdm
Screen 0: minimum 8 x 8, current 3840 x 1200, maximum 8192 x 8192
DVI-I-0 disconnected (normal left inverted right x axis y axis)
VGA-0 connected 1920x1200+0+0 (normal left inverted right x axis y axis) 518mm x 324mm
   1920x1200      60.0*+
   1600x1200      75.0     70.0     65.0     60.0  
   1280x1024      75.0     60.0  
   1280x960       60.0  
   1152x864       75.0  
   1024x768       75.0     70.1     60.0  
   800x600        75.0     72.2     60.3     56.2  
   640x480        75.0     72.8     59.9  
TV-0 disconnected (normal left inverted right x axis y axis)
DVI-I-1 connected 1920x1200+1920+0 (normal left inverted right x axis y axis) 518mm x 324mm
   1920x1200      60.0*+
   1680x1050      60.0  
   1600x1200      60.0  
   1280x1024      75.0     60.0  
   1280x960       75.0  
   1024x768       75.0     60.0  
   800x600        75.0     60.3  
   640x480        75.0     59.9  
->

Julia

Translation of: Phix

<lang julia> if Base.Sys.islinux()

   run(`xrandr -s 640x480`)
   sleep(3)
   run(`xrandr -s 1280x960`)

else # windows

   run(`mode CON: COLS=40 LINES=100`)
   sleep(3)
   run(`mode CON: COLS=100 LINES=50`)

end </lang>

Kotlin

Translation of: UNIX Shell
Works with: Ubuntu 14.04

<lang scala>// version 1.1.51

import java.util.Scanner

fun runSystemCommand(command: String) {

   val proc = Runtime.getRuntime().exec(command)
   Scanner(proc.inputStream).use {
       while (it.hasNextLine()) println(it.nextLine())
   }
   proc.waitFor()
   println()

}

fun main(args: Array<String>) {

   // query supported display modes  
   runSystemCommand("xrandr -q")
   Thread.sleep(3000)
   // change display mode to 1024x768 say (no text output)
   runSystemCommand("xrandr -s 1024x768")
   Thread.sleep(3000)
   // change it back again to 1366x768 (or whatever is optimal for your system)
   runSystemCommand("xrandr -s 1366x768")

}</lang>

Output:
Screen 0: minimum 320 x 200, current 1366 x 768, maximum 32767 x 32767
eDP1 connected primary 1366x768+0+0 (normal left inverted right x axis y axis) 344mm x 193mm
   1366x768       60.0*+   48.0  
   1360x768       59.8     60.0  
   1024x768       60.0  
   800x600        60.3     56.2  
   640x480        59.9  
HDMI1 disconnected (normal left inverted right x axis y axis)
DP1 disconnected (normal left inverted right x axis y axis)
HDMI2 disconnected (normal left inverted right x axis y axis)
HDMI3 disconnected (normal left inverted right x axis y axis)
DP2 disconnected (normal left inverted right x axis y axis)
VIRTUAL1 disconnected (normal left inverted right x axis y axis)

Locomotive Basic

The Amstrad CPC464 supports three video modes:

  • Mode 0 - Graphics: 160x200 Text: 20x25 Colours: 16
  • Mode 1 - Graphics: 320x200 Text: 40x25 Colours: 4
  • Mode 2 - Graphics: 640x200 Text: 80x25 Colours: 2

Note that text can be displayed using conventional means in all display modes. <lang locobasic>10 MODE 0: REM switch to mode 0</lang>


Nim

Works with: Linux

Using the command "xrandr" on Linux systems. <lang Nim>import os, osproc, strformat, strscans

  1. Retrieve video modes.

let p = startProcess("xrandr", "", ["-q"], nil, {poUsePath}) var currWidth, currHeight = 0 # Current video mode. var width, height = 0 # Some other video mode. for line in p.lines:

 echo line
 # Find current display mode, marked by an asterisk.
 var f: float
 if currWidth == 0:
   # Find current width and height.
   discard line.scanf(" $s$ix$i $s$f*", currWidth, currHeight, f)
 elif width == 0:
   # Find another width and height.
   discard line.scanf(" $s$ix$i $s$f", width, height, f)

p.close()

  1. Change video mode.

let newMode = &"{width}x{height}" sleep 1000 echo "\nSwitching to ", newMode sleep 2000 discard execProcess("xrandr", "", ["-s", newMode], nil, {poUsePath})

  1. Restore previous video mode.

let prevMode = &"{currWidth}x{currHeight}" sleep 1000 echo "\nSwitching back to ", prevMode sleep 2000 discard execProcess("xrandr", "", ["-s", prevMode], nil, {poUsePath})</lang>

Output:

Some possible output:

Screen 0: minimum 8 x 8, current 1920 x 1080, maximum 32767 x 32767
eDP1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 310mm x 170mm
   1920x1080     60.01*+  59.93  
   1680x1050     59.95    59.88  
   1400x1050     59.98  
   1600x900      60.00    59.95    59.82  
   1280x1024     60.02  
   1400x900      59.96    59.88  
   1280x960      60.00  
   1368x768      60.00    59.88    59.85  
   1280x800      59.81    59.91  
   1280x720      59.86    60.00    59.74  
   1024x768      60.00  
   1024x576      60.00    59.90    59.82  
   960x540       60.00    59.63    59.82  
   800x600       60.32    56.25  
   864x486       60.00    59.92    59.57  
   640x480       59.94  
   720x405       59.51    60.00    58.99  
   640x360       59.84    59.32    60.00  
HDMI1 disconnected (normal left inverted right x axis y axis)
VIRTUAL1 disconnected (normal left inverted right x axis y axis)

Switching to 1680x1050

Switching back to 1920x1080

Perl

Same caveats as with Raku.

Translation of: Raku

<lang perl>$| = 1;

my @info = `xrandr -q`; $info[0] =~ /current (\d+) x (\d+)/; my $current = "$1x$2";

my @resolutions; for (@info) {

   push @resolutions, $1 if /^\s+(\d+x\d+)/

}

system("xrandr -s $resolutions[-1]"); print "Current resolution $resolutions[-1].\n"; for (reverse 1 .. 9) {

   print "\rChanging back in $_ seconds...";
   sleep 1;

} system("xrandr -s $current"); print "\rResolution returned to $current.\n";</lang>

Phix

<lang Phix>if platform()=LINUX then

   {} = system_exec("xrandr -s 640x480")
   sleep(3)
   {} = system_exec("xrandr -s 1280x960")

else -- WINDOWS

   puts(1,"") -- (ensure console exists)
   system("mode CON: COLS=40 LINES=25")
   sleep(3)
   system("mode CON: COLS=80 LINES=25")

end if</lang> Obviously running xrandr -q or mode -? will tell you more.

Python

Library: win32api
Library: win32con

This program changes the resolution the screen is running at to 640x480. <lang python>import win32api import win32con import pywintypes devmode=pywintypes.DEVMODEType() devmode.PelsWidth=640 devmode.PelsHeight=480 devmode.Fields=win32con.DM_PELSWIDTH | win32con.DM_PELSHEIGHT win32api.ChangeDisplaySettings(devmode,0)</lang>

QBasic

This example is wrong! QBASIC can use EGA/VGA Graphics until SCREEN 13 (320x200 - 256 colors) or SCREEN 12 (640x480 - 16 colors).QBASIC version used: 1.1 <lang qbasic>'QBasic can switch VGA modes SCREEN 18 'Mode 12h 640x480 16 colour graphics</lang>

Raku

(formerly Perl 6) Raku runs on several different operating systems over many different architectures so can not easily assume direct control over hardware. Instead, like most modern programming languages, it relies on the current OS and windowing system to provide APIs.

Here is an example which will work for most Debian based Linuxs (and probably others) running some variant of X11 with a single active monitor.

Works with: Rakudo version 2018.05

<lang perl6>my @info = QX('xrandr -q').lines;

@info[0] ~~ /<?after 'current '>(\d+) ' x ' (\d+)/; my $current = "$0x$1";

my @resolutions; @resolutions.push: $0 if $_ ~~ /^\s+(\d+'x'\d+)/ for @info;

QX("xrandr -s @resolutions[*-1]"); say "Current resolution {@resolutions[*-1]}."; for 9 ... 1 {

   print "\rChanging back in $_ seconds...";
   sleep 1;

} QX("xrandr -s $current"); say "\rResolution returned to {$current}. ";</lang>

REXX

This method only works in DOS prompt either under (native) DOS or Microsoft WINDOWS.

DOS (under Microsoft Windows) will support:

  • columns   of   11 ──> 32,766   (inclusive)
  • lines         of   1 ──> 32,766   (inclusive)

version 1: no checking for which OS

<lang rexx>/*REXX program to switch video display modes based on columns and lines.*/

parse arg cols lines . 'MODE' "CON: COLS="cols 'LINES='lines

                                      /*stick a fork in it, we're done.*/</lang>

version 2: checks for which OS

The prologue code (at the bottom of the program) is a collection of some general-purpose subroutines which determine:

  • which environment (operating system) the REXX interpreter is running under
  • if Windows/NT/XP/Vista/7/8 (the NT family) is running
  • which REXX is being executed
  • what literal to use to obtain the environmental variables (for the value bif)
  • what the fileName, fileType/fileExt, fileMode/path is of the REXX program
  • which command to use to clear the terminal screen
  • invokes $H to show general documentation (1st and only arg = ?)
  • invokes $H to show a flow diagram (1st and only arg = ?FLOW)
  • invokes $H to show sample uses (1st and only arg = ?SAMPLE)
  • invokes $H to show the author & contact info (1st and only arg = ?AUTHOR)

All the prologue was left intact to give a general feel of the scope of the boilerplate code. The prologue code is in many REXX programs and it's easier to keep them on one line for copying purposes and sorting. <lang rexx>/*REXX program to switch video display modes based on columns and lines.*/ parse arg !; if !all() then exit /*exit if documentation specified*/ if \!dos & \!os2 then exit /*if this isn't DOS, then exit. */

parse arg cols lines . 'MODE' "CON: COLS="cols 'LINES='lines

exit /*stick a fork in it, we're done.*/ /*══════════════════════════════════general 1-line subs═════════════════*/ !all:!!=!;!=space(!);upper !;call !fid;!nt=right(!var('OS'),2)=='NT';!cls=word('CLS VMFCLEAR CLRSCREEN',1+!cms+!tso*2);if arg(1)\==1 then return 0;if wordpos(!,'? ?SAMPLES ?AUTHOR ?FLOW')==0 then return 0;!call=']$H';call '$H' !fn !;!call=;return 1 !cal:if symbol('!CALL')\=="VAR" then !call=;return !call !env:!env='ENVIRONMENT';if !sys=='MSDOS'|!brexx|!r4|!roo then !env='SYSTEM';if !os2 then !env='OS2'!env;!ebcdic=1=='f0'x;return !fid:parse upper source !sys !fun !fid . 1 . . !fn !ft !fm .;call !sys;if !dos then do;_=lastpos('\',!fn);!fm=left(!fn,_);!fn=substr(!fn,_+1);parse var !fn !fn '.' !ft;end;return word(0 !fn !ft !fm,1+('0'arg(1))) !rex:parse upper version !ver !vernum !verdate .;!brexx='BY'==!vernum;!kexx='KEXX'==!ver;!pcrexx='REXX/PERSONAL'==!ver|'REXX/PC'==!ver;!r4='REXX-R4'==!ver;!regina='REXX-REGINA'==left(!ver,11);!roo='REXX-ROO'==!ver;call !env;return !sys:!cms=!sys=='CMS';!os2=!sys=='OS2';!tso=!sys=='TSO'|!sys=='MVS';!vse=!sys=='VSE';!dos=pos('DOS',!sys)\==0|pos('WIN',!sys)\==0|!sys=='CMD';call !rex;return !var:call !fid;if !kexx then return space(dosenv(arg(1)));return space(value(arg(1),,!env))</lang>

Ring

<lang ring> system("mode 40, 25") </lang>

Scala

Translation of: UNIX Shell
Works with: Ubuntu 14.04

<lang scala>object VideoDisplayModes extends App {

 import java.util.Scanner
 def runSystemCommand(command: String) {
   val proc = Runtime.getRuntime.exec(command)
   val a: Unit = {
     val a = new Scanner(proc.getInputStream)
     while (a.hasNextLine) println(a.nextLine())
   }
   proc.waitFor()
   println()
 }
 // query supported display modes
 runSystemCommand("xrandr -q")
 Thread.sleep(3000)
 // change display mode to 1024x768 say (no text output)
 runSystemCommand("xrandr -s 1024x768")
 Thread.sleep(3000)
 // change it back again to 1366x768 (or whatever is optimal for your system)
 runSystemCommand("xrandr -s 1366x768")

}</lang>

smart BASIC

GRAPHICS switches to graphics view (as opposed to text view).

GRAPHICS MODE X sets graphics commands compositing mode to X, where X is one of the following modes:

CLEAR, COLOR, COLORBURN, COLORDODGE, COPY, DARKEN, DESTATOP, DESTIN, DESTOUT, DESTOVER, DIFFERENCE, EXCLUSION, HARDLIGHT, HUE, LIGHTEN, LUMINOSITY, MULTIPLY, NORMAL (default), OVERLAY, PLUSDARKER, PLUSLIGHTER, SATURATION, SCREEN, SOFTLIGHT, SOURCEATOP, SOURCEIN, SOURCEOUT, XOR.

EXAMPLE: <lang qbasic>GRAPHICS FILL RECT 50,50 SIZE 50 GRAPHICS MODE CLEAR FILL RECT 50,50 SIZE 25</lang>

UNIX Shell

If the system runs X11 and supports XRANDR, then <lang bash>$ xrandr -q</lang> lists the available modes, and <lang bash>$ xrandr -s 1024x768</lang> sets the screen to the given size.

With modern LCD monitors, this feature is not very useful. These monitors have a single best mode, and the X server discovers and uses that mode by default. Smaller screen modes might work, but make a blurry picture.

Wren

The ability to call external processes such as xrandr is expected to be added to Wren-cli in the next release. In the meantime, we embed the following Wren script in a minimal C host (no error checking) to complete this task. <lang ecmascript>/* video_display_modes.wren */

class C {

   foreign static xrandr(args)
   foreign static usleep(usec)

}

// query supported display modes C.xrandr("-q")

C.usleep(3000)

// change display mode to 1368x768 System.print("\nChanging to 1368 x 768 mode.") C.xrandr("-s 1368x768")

C.usleep(3000)

// change it back again to 1920x1080 System.print("\nReverting to 1920 x 1080 mode.") C.xrandr("-s 1920x1080")</lang>
We now embed this in the following C program, compile and run it. <lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <string.h>
  3. include <unistd.h>
  4. include "wren.h"

void C_xrandr(WrenVM* vm) {

    const char *arg = wrenGetSlotString(vm, 1);
    char command[strlen(arg) + 8];
    strcpy(command, "xrandr ");
    strcat(command, arg);
    system(command);

}

void C_usleep(WrenVM* vm) {

   useconds_t usec = (useconds_t)wrenGetSlotDouble(vm, 1);
   usleep(usec);

}

WrenForeignMethodFn bindForeignMethod(

   WrenVM* vm,
   const char* module,
   const char* className,
   bool isStatic,
   const char* signature) {
   if (strcmp(module, "main") == 0) {
       if (strcmp(className, "C") == 0) {
           if (isStatic && strcmp(signature, "xrandr(_)") == 0) return C_xrandr;
           if (isStatic && strcmp(signature, "usleep(_)") == 0) return C_usleep;
       }
   }
   return NULL;

}

static void writeFn(WrenVM* vm, const char* text) {

   printf("%s", text);

}

char *readFile(const char *fileName) {

   FILE *f = fopen(fileName, "r");
   fseek(f, 0, SEEK_END);
   long fsize = ftell(f);
   rewind(f);
   char *script = malloc(fsize + 1);
   fread(script, 1, fsize, f);
   fclose(f);
   script[fsize] = 0;
   return script;

}

int main(int argc, char **argv) {

   WrenConfiguration config;
   wrenInitConfiguration(&config);
   config.writeFn = &writeFn;
   config.bindForeignMethodFn = &bindForeignMethod;
   WrenVM* vm = wrenNewVM(&config);
   const char* module = "main";
   const char* fileName = "video_display_modes.wren";
   char *script = readFile(fileName);
   wrenInterpret(vm, module, script);
   wrenFreeVM(vm);
   free(script);
   return 0;

}</lang>

Output:
Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 16384 x 16384
eDP-1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 344mm x 193mm
   1920x1080     60.01*+  60.01    59.97    59.96    59.93  
   1680x1050     59.95    59.88  
   1600x1024     60.17  
   1400x1050     59.98  
   1600x900      59.99    59.94    59.95    59.82  
   1280x1024     60.02  
   1440x900      59.89  
   1400x900      59.96    59.88  
   1280x960      60.00  
   1440x810      60.00    59.97  
   1368x768      59.88    59.85  
   1360x768      59.80    59.96  
   1280x800      59.99    59.97    59.81    59.91  
   1152x864      60.00  
   1280x720      60.00    59.99    59.86    59.74  
   1024x768      60.04    60.00  
   960x720       60.00  
   928x696       60.05  
   896x672       60.01  
   1024x576      59.95    59.96    59.90    59.82  
   960x600       59.93    60.00  
   960x540       59.96    59.99    59.63    59.82  
   800x600       60.00    60.32    56.25  
   840x525       60.01    59.88  
   864x486       59.92    59.57  
   800x512       60.17  
   700x525       59.98  
   800x450       59.95    59.82  
   640x512       60.02  
   720x450       59.89  
   700x450       59.96    59.88  
   640x480       60.00    59.94  
   720x405       59.51    58.99  
   684x384       59.88    59.85  
   680x384       59.80    59.96  
   640x400       59.88    59.98  
   576x432       60.06  
   640x360       59.86    59.83    59.84    59.32  
   512x384       60.00  
   512x288       60.00    59.92  
   480x270       59.63    59.82  
   400x300       60.32    56.34  
   432x243       59.92    59.57  
   320x240       60.05  
   360x202       59.51    59.13  
   320x180       59.84    59.32  
DP-1 disconnected (normal left inverted right x axis y axis)
HDMI-1 disconnected (normal left inverted right x axis y axis)
HDMI-2 disconnected (normal left inverted right x axis y axis)

Changing to 1368 x 768 mode.

Reverting to 1920 x 1080 mode.

XPL0

<lang XPL0>code SetVid=45; SetVid(Mode)</lang> Any display mode supported by the IBM-PC-compatible hardware and by the VGA or VESA standards can be enabled by calling the SetVid intrinsic routine. This works without problem on computers booted into DOS and under versions of Windows up until XP. DOSBox[1] gets around most of the incompatibilities introduced by WinXP and later versions.

Example display modes:

$03 - CGA 80x25 text in 16 colors (x4)
$12 - VGA 640x480x4 graphics
$13 - VGA 320x200x8
$101 - VESA 640x480x8
$118 - VESA 1024x768x24

On modern LCD displays (as opposed to older CRT monitors) images can look terrible if the selected mode does not match the native resolution of the LCD.