├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── arg.h ├── config.mk ├── dattr.c ├── lsd.c ├── man ├── Makefile ├── dattr.1 ├── lsd.1 ├── pfd.1 ├── phd.1 └── ppd.1 ├── pfd.c ├── phd.c ├── ppd.c ├── randr.c ├── randr.h ├── util.c └── util.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.core 3 | lsd 4 | pfd 5 | ppd 6 | phd 7 | dattr 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2014-2017 Tudor Roman , 4 | Abraham Levine 5 | 6 | Permission to use, copy, modify, and distribute this software for any 7 | purpose with or without fee is hereby granted, provided that the above 8 | copyright notice and this permission notice appear in all copies. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 11 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 12 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 13 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 14 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 15 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | PERFORMANCE OF THIS SOFTWARE. 17 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include config.mk 2 | 3 | HDR = util.h randr.h 4 | SRC = lsd.c dattr.c pfd.c ppd.c phd.c 5 | 6 | OBJ = $(SRC:.c=.o) 7 | BIN = $(SRC:.c=) 8 | 9 | .POSIX: 10 | 11 | all: binutils 12 | 13 | binutils: $(BIN) 14 | 15 | manpages: 16 | cd man; $(MAKE) $(MFLAGS) 17 | 18 | $(OBJ): $(HDR) util.o randr.o 19 | 20 | .o: 21 | @echo "LD $@" 22 | @$(LD) $< -o $@ $(LDFLAGS) util.o randr.o 23 | 24 | .c.o: 25 | @echo "CC $<" 26 | @$(CC) -c $< -o $@ $(CFLAGS) 27 | 28 | install: $(BIN) 29 | mkdir -p $(DESTDIR)$(PREFIX)/bin/ 30 | cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin/ 31 | cd man; $(MAKE) $(MFLAGS) install 32 | 33 | uninstall: 34 | @echo "uninstalling binaries" 35 | @for util in $(BIN); do \ 36 | rm -f $(DESTDIR)$(PREFIX)/bin/$$util; \ 37 | done 38 | cd man; $(MAKE) $(MFLAGS) uninstall 39 | 40 | clean: 41 | rm -f $(OBJ) $(BIN) util.o randr.o 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | disputils 2 | ========= 3 | 4 | disputils is a set of utilities for querying information about connected X 5 | displays. 6 | 7 | Example 8 | ------- 9 | 10 | The following script puts the current focused window in the middle of the 11 | current monitor rather than at the center of the root window. Requires 12 | [the wmutils core](https://github.com/wmutils/core/). 13 | 14 | ```bash 15 | #!/bin/sh 16 | 17 | # get display, wid, w/h, border width 18 | MON=$(pfd) 19 | WID=$(pfw) 20 | WW=$(wattr w $WID) 21 | WH=$(wattr h $WID) 22 | BW=$(wattr b $WID) 23 | 24 | # get monitor xywh 25 | SW=$(dattr w $MON) 26 | SH=$(dattr h $MON) 27 | SX=$(dattr x $MON) 28 | SY=$(dattr y $MON) 29 | 30 | # move the window to the center 31 | wtp $((SW/2 + SX - WW/2 - BW)) $((SH/2 - SY - WH/2 - BW)) $WW $WH $WID 32 | ``` 33 | 34 | Utilities 35 | --------- 36 | 37 | Here is the current list of utilities: 38 | 39 | * `dattr` - get display's attributes (coordinates, size) 40 | * `lsd` - list displays 41 | * `pfd` - print focused display (the display that contains the currently 42 | focused window) 43 | * `phd` - print hovered display (the display that contains the mouse 44 | pointer) 45 | * `ppd` - print primary display 46 | 47 | Dependencies 48 | ------------ 49 | 50 | disputils relies on the XCB and XCB_randr libraries. 51 | 52 | License 53 | ------- 54 | 55 | All files of the disputils project is released under the [ISC][license] license. See the 56 | `LICENSE` file. 57 | 58 | [license]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/share/misc/license.template?rev=HEAD 59 | 60 | Download, build and install 61 | -------------------- 62 | 63 | The default `PREFIX` is `/usr/local`. You can override all variables from the 64 | `config.mk` file. 65 | 66 | ``` 67 | $ git clone git://github.com/tudurom/disputils.git && cd disputils 68 | $ make 69 | # make install 70 | ``` 71 | 72 | -------------------------------------------------------------------------------- /arg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copy me if you can. 3 | * by 20h 4 | */ 5 | 6 | #ifndef ARG_H__ 7 | #define ARG_H__ 8 | 9 | extern char *argv0; 10 | 11 | /* use main(int argc, char *argv[]) */ 12 | #define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ 13 | argv[0] && argv[0][1]\ 14 | && argv[0][0] == '-';\ 15 | argc--, argv++) {\ 16 | char argc_;\ 17 | char **argv_;\ 18 | int brk_;\ 19 | if (argv[0][1] == '-' && argv[0][2] == '\0') {\ 20 | argv++;\ 21 | argc--;\ 22 | break;\ 23 | }\ 24 | for (brk_ = 0, argv[0]++, argv_ = argv;\ 25 | argv[0][0] && !brk_;\ 26 | argv[0]++) {\ 27 | if (argv_ != argv)\ 28 | break;\ 29 | argc_ = argv[0][0];\ 30 | switch (argc_) 31 | 32 | /* Handles obsolete -NUM syntax */ 33 | #define ARGNUM case '0':\ 34 | case '1':\ 35 | case '2':\ 36 | case '3':\ 37 | case '4':\ 38 | case '5':\ 39 | case '6':\ 40 | case '7':\ 41 | case '8':\ 42 | case '9' 43 | 44 | #define ARGEND }\ 45 | } 46 | 47 | #define ARGC() argc_ 48 | 49 | #define ARGNUMF(base) (brk_ = 1, estrtol(argv[0], (base))) 50 | 51 | #define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ 52 | ((x), abort(), (char *)0) :\ 53 | (brk_ = 1, (argv[0][1] != '\0')?\ 54 | (&argv[0][1]) :\ 55 | (argc--, argv++, argv[0]))) 56 | 57 | #define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ 58 | (char *)0 :\ 59 | (brk_ = 1, (argv[0][1] != '\0')?\ 60 | (&argv[0][1]) :\ 61 | (argc--, argv++, argv[0]))) 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /config.mk: -------------------------------------------------------------------------------- 1 | PREFIX = /usr/local 2 | MANPREFIX = $(PREFIX)/share/man 3 | 4 | CC = cc 5 | LD = $(CC) 6 | 7 | CFLAGS += -std=c99 -D_XOPEN_SOURCE=700 `pkg-config --cflags xcb xcb-randr` -pedantic -Wall -O2 8 | LDFLAGS += `pkg-config --libs xcb xcb-randr` 9 | -------------------------------------------------------------------------------- /dattr.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "randr.h" 10 | #include "util.h" 11 | 12 | xcb_connection_t *conn; 13 | xcb_screen_t *scrn; 14 | 15 | void 16 | usage(char *name) 17 | { 18 | printf("usage: %s [whxy] \n", name); 19 | exit(0); 20 | } 21 | 22 | int 23 | main(int argc, char *argv[]) 24 | { 25 | #ifdef __OpenBSD__ 26 | if (pledge("stdio rpath unix", NULL) == -1) 27 | err(1, "pledge"); 28 | #endif 29 | xcb_randr_output_t output = -1; 30 | xcb_randr_get_output_info_reply_t *output_info = NULL; 31 | xcb_randr_crtc_t screen_crtc; 32 | xcb_randr_get_crtc_info_reply_t *screen_crtc_info = NULL; 33 | char *output_name; 34 | 35 | if (argc == 2) 36 | output_name = argv[1]; 37 | else if (argc == 3) 38 | output_name = argv[2]; 39 | else 40 | usage(argv[0]); 41 | 42 | init_xcb(&conn); 43 | get_screen(conn, &scrn); 44 | 45 | xcb_randr_provider_t *providers; 46 | int p_len = get_providers(conn, scrn, &providers); 47 | 48 | /* get the id of the output */ 49 | int i = 0; 50 | while (i < p_len && output == -1) { 51 | xcb_randr_output_t *os; 52 | int o_len = get_outputs(conn, providers[i], &os); 53 | 54 | int j = 0; 55 | while (j < o_len && output == -1) { 56 | if (strcmp(output_name, 57 | (const char *)get_output_name(conn, os[j])) == 0) 58 | output = os[j]; 59 | 60 | j++; 61 | } 62 | 63 | i++; 64 | } 65 | 66 | if (output == -1) { 67 | errx(1, "Output not found"); 68 | } 69 | output_info = get_output_info(conn, output); 70 | 71 | /* get info about output */ 72 | screen_crtc = output_info->crtc; 73 | screen_crtc_info = get_output_crtc_info(conn, screen_crtc); 74 | if (screen_crtc_info == '\0') 75 | errx(1, "Output not in use"); 76 | 77 | if (argc == 3) { 78 | /* print info */ 79 | for (i = 0; i < strlen(argv[1]); i++) { 80 | switch (argv[1][i]) { 81 | case 'w': 82 | printf("%d\n", screen_crtc_info->width); 83 | break; 84 | case 'h': 85 | printf("%d\n", screen_crtc_info->height); 86 | break; 87 | case 'x': 88 | printf("%d\n", screen_crtc_info->x); 89 | break; 90 | case 'y': 91 | printf("%d\n", screen_crtc_info->y); 92 | break; 93 | default: 94 | usage(argv[0]); 95 | } 96 | } 97 | } 98 | 99 | free(output_info); 100 | free(screen_crtc_info); 101 | kill_xcb(&conn); 102 | return 0; 103 | } 104 | -------------------------------------------------------------------------------- /lsd.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "randr.h" 10 | #include "util.h" 11 | 12 | xcb_connection_t *conn; 13 | xcb_screen_t *scrn; 14 | 15 | void 16 | usage(char *name) 17 | { 18 | printf("usage: %s \n", name); 19 | exit(0); 20 | } 21 | 22 | void 23 | print_output(xcb_connection_t *conn, xcb_randr_output_t output) 24 | { 25 | uint8_t* name = get_output_name(conn, output); 26 | if (get_output_connection(conn, output) == 0) { 27 | printf("%s\n", name); 28 | } 29 | } 30 | 31 | int 32 | main(int argc, char *argv[]) 33 | { 34 | xcb_randr_get_output_info_reply_t *output_info; 35 | xcb_randr_get_crtc_info_reply_t *output_crtc_info; 36 | int print_all = 0; 37 | if (argc > 1 && strcmp(argv[1], "-a") == 0) 38 | print_all = 1; 39 | 40 | #ifdef __OpenBSD__ 41 | if (pledge("stdio rpath unix", NULL) == -1) 42 | err(1, "pledge"); 43 | #endif 44 | if (argc > 1 && (argc == 2 && !print_all)) 45 | usage(argv[0]); 46 | init_xcb(&conn); 47 | get_screen(conn, &scrn); 48 | 49 | xcb_randr_provider_t *providers; 50 | int p_len = get_providers(conn, scrn, &providers); 51 | 52 | for (int i = 0; i < p_len; i++) { 53 | xcb_randr_output_t *os; 54 | int o_len = get_outputs(conn, providers[i], &os); 55 | 56 | /* Print screens from providers */ 57 | for (int j = 0; j < o_len; j++) { 58 | output_info = get_output_info(conn, os[j]); 59 | output_crtc_info = get_output_crtc_info(conn, output_info->crtc); 60 | /* Print screen only if in use */ 61 | if (print_all || output_crtc_info != NULL) { 62 | print_output(conn, os[j]); 63 | } 64 | } 65 | } 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /man/Makefile: -------------------------------------------------------------------------------- 1 | include ../config.mk 2 | 3 | MAN = \ 4 | lsd.1 \ 5 | pfd.1 \ 6 | ppd.1 \ 7 | phd.1 \ 8 | dattr.1 \ 9 | 10 | .POSIX: 11 | 12 | install: $(MAN) 13 | mkdir -p $(DESTDIR)$(MANPREFIX)/man1/ 14 | cp -f $(MAN) $(DESTDIR)$(MANPREFIX)/man1/ 15 | 16 | uninstall: 17 | @echo "uninstalling manpages" 18 | @for page in $(MAN); do \ 19 | rm -f $(DESTDIR)$(MANPREFIX)/man1/$$page; \ 20 | done 21 | -------------------------------------------------------------------------------- /man/dattr.1: -------------------------------------------------------------------------------- 1 | '\" e 2 | .Dd April 16, 2016 3 | .Dt DATTR 1 4 | .Os disputils 5 | .Sh NAME 6 | .Nm dattr 7 | .Nd get display attributes 8 | .Sh SYNOPSIS 9 | .Nm dattr 10 | .Op Cm whxy 11 | .Ar display_id 12 | .Sh DESCRIPTION 13 | .Nm 14 | prints information about the display 15 | .Ar display_id 16 | to 17 | .Dv stdout . 18 | .Pp 19 | What information is presented depends on the commands given to 20 | .Nm . 21 | The queried arguments are printed in the order they are requested, 22 | spearated by a space. If no commands are given, 23 | .Nm 24 | will return 0 if 25 | .Ar display_id 26 | exists, and 1 otherwise. 27 | .Bl -tag -display_idth Ds 28 | .It Cm w 29 | Print 30 | .Ar display_id Ns \(cqs width. 31 | .It Cm h 32 | Print 33 | .Ar display_id Ns \(cqs 34 | height. 35 | .It Cm x 36 | Print 37 | .Ar display_id Ns \(cqs 38 | .EQ 39 | x 40 | .EN 41 | offset. 42 | .It Cm y 43 | Print 44 | .Ar display_id Ns \(cqs 45 | .EQ 46 | y 47 | .EN 48 | offset. 49 | .El 50 | .Sh ENVIRONMENT 51 | .Nm 52 | acts on the X display specified by the 53 | .Ev DISPLAY 54 | variable. 55 | .Sh EXAMPLES 56 | .Dl $ dattr whxy LVDS-1 57 | .Dl 1600 900 1920 0 58 | .Pp 59 | .Dl $ dattr wh DP-1 60 | .Dl 1920 1080 61 | -------------------------------------------------------------------------------- /man/lsd.1: -------------------------------------------------------------------------------- 1 | .Dd April 16, 2016 2 | .Dt LSD 1 3 | .Os disputils 4 | .Sh NAME 5 | .Nm lsd 6 | .Nd list connected displays 7 | .Sh SYNOPSIS 8 | .Nm 9 | .Op Fl a 10 | .Sh DESCRIPTION 11 | .Nm 12 | lists connected displays. 13 | .Pp 14 | By default, 15 | .Nm 16 | lists only displays that are in use. 17 | .Bl -tag -width Ds 18 | .It Fl a 19 | List all connected displays, not only those who are in use. 20 | .El 21 | .Sh ENVIRONMENT 22 | .Nm 23 | acts on the X display specified by the 24 | .Ev DISPLAY 25 | variable 26 | .Sh SEE ALSO 27 | .Xr dattr 1 28 | -------------------------------------------------------------------------------- /man/pfd.1: -------------------------------------------------------------------------------- 1 | .Dd April 16, 2016 2 | .Dt PFD 1 3 | .Os disputils 4 | .Sh NAME 5 | .Nm pfd 6 | .Nd print monitor containing the focused window 7 | .Sh SYNOPSIS 8 | .Nm pfd 9 | .Op Fl w Ar wid 10 | .Sh DESCRIPTION 11 | Print the ID of the monitor containing 12 | .Ar wid 13 | or the currently focused window (if 14 | .Ar wid 15 | is not specified) to 16 | .Dv stdout . 17 | .Sh ENVIRONMENT 18 | .Nm 19 | acts on the X display specified by the 20 | .Ev DISPLAY 21 | variable. 22 | -------------------------------------------------------------------------------- /man/phd.1: -------------------------------------------------------------------------------- 1 | .Dd April 16, 2016 2 | .Dt PHD 1 3 | .Os disputils 4 | .Sh NAME 5 | .Nm phd 6 | .Nd print monitor containing the pointer (print hovered display) 7 | .Sh SYNOPSIS 8 | .Nm phd 9 | .Sh DESCRIPTION 10 | Print the ID of the monitor containing the pointer to 11 | .Dv stdout . 12 | .Sh ENVIRONMENT 13 | .Nm 14 | acts on the X display specified by the 15 | .Ev DISPLAY 16 | variable. 17 | -------------------------------------------------------------------------------- /man/ppd.1: -------------------------------------------------------------------------------- 1 | .Dd April 16, 2016 2 | .Dt PPD 1 3 | .Os disputils 4 | .Sh NAME 5 | .Nm pfd 6 | .Nd print primary display 7 | .Sh SYNOPSIS 8 | .Nm pfd 9 | .Sh DESCRIPTION 10 | Print the ID of the current primary display to 11 | .Dv stdout . 12 | .Sh ENVIRONMENT 13 | .Nm 14 | acts on the X display specified by the 15 | .Ev DISPLAY 16 | variable. 17 | -------------------------------------------------------------------------------- /pfd.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "arg.h" 10 | #include "randr.h" 11 | #include "util.h" 12 | 13 | xcb_connection_t *conn; 14 | xcb_screen_t *scrn; 15 | 16 | void 17 | usage(char *name) 18 | { 19 | printf("usage: %s [-w wid]\n", name); 20 | exit(0); 21 | } 22 | 23 | bool 24 | window_exists(xcb_window_t win) { 25 | xcb_get_geometry_reply_t *r = 26 | xcb_get_geometry_reply(conn, 27 | xcb_get_geometry(conn, win), NULL); 28 | 29 | return r != NULL; 30 | } 31 | 32 | int 33 | main(int argc, char *argv[]) 34 | { 35 | #ifdef __OpenBSD__ 36 | if (pledge("stdio rpath unix", NULL) == -1) 37 | err(1, "pledge"); 38 | #endif 39 | xcb_window_t f_window; 40 | xcb_get_geometry_reply_t *window_geometry = NULL; 41 | 42 | uint16_t window_x; 43 | uint16_t window_y; 44 | 45 | xcb_randr_get_output_info_reply_t *output_info = NULL; 46 | xcb_randr_get_crtc_info_reply_t *output_crtc_info = NULL; 47 | xcb_randr_output_t output; 48 | const char *output_name; 49 | 50 | uint16_t output_w; 51 | uint16_t output_h; 52 | uint16_t output_x; 53 | uint16_t output_y; 54 | 55 | char *argv0; 56 | 57 | init_xcb(&conn); 58 | get_screen(conn, &scrn); 59 | 60 | f_window = get_focused_window(conn); 61 | /* Get info about the focused window */ 62 | ARGBEGIN { 63 | case 'w': 64 | f_window = strtoul(EARGF(usage(argv0)), NULL, 16); 65 | } ARGEND 66 | 67 | if (!window_exists(f_window)) 68 | errx(1, "Window does not exist"); 69 | window_geometry = get_window_geometry(conn, f_window); 70 | window_x = window_geometry->x; 71 | window_y = window_geometry->y; 72 | 73 | /* Iterate through outputs */ 74 | xcb_randr_provider_t *providers; 75 | int p_len = get_providers(conn, scrn, &providers); 76 | 77 | int i = 0; 78 | output_name = NULL; 79 | while (i < p_len && output_name == NULL) { 80 | xcb_randr_output_t *os; 81 | int o_len = get_outputs(conn, providers[i], &os); 82 | 83 | int j = 0; 84 | while (j < o_len && output_name == NULL) { 85 | output = os[j]; 86 | if (get_output_connection(conn, output) == 0) { 87 | /* Check */ 88 | output_info = get_output_info(conn, output); 89 | output_crtc_info = get_output_crtc_info(conn, output_info->crtc); 90 | if (output_crtc_info != NULL) { 91 | output_w = output_crtc_info->width; 92 | output_h = output_crtc_info->height; 93 | output_x = output_crtc_info->x; 94 | output_y = output_crtc_info->y; 95 | 96 | if (window_x >= output_x && 97 | window_y >= output_y && 98 | window_x < output_x + output_w && 99 | window_y < output_y + output_h) { 100 | 101 | output_name = (const char *)get_output_name(conn, output); 102 | } 103 | } 104 | } 105 | j++; 106 | } 107 | 108 | i++; 109 | } 110 | if (output_name == NULL) 111 | errx(1, "Cannot get output name"); 112 | printf("%s\n", output_name); 113 | free(window_geometry); 114 | free(output_info); 115 | free(output_crtc_info); 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /phd.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "randr.h" 9 | #include "util.h" 10 | 11 | xcb_connection_t *conn; 12 | xcb_screen_t *scrn; 13 | 14 | void 15 | usage(char *name) 16 | { 17 | printf("usage: %s \n", name); 18 | exit(0); 19 | } 20 | 21 | int 22 | main(int argc, char *argv[]) 23 | { 24 | #ifdef __OpenBSD__ 25 | if (pledge("stdio rpath unix", NULL) == -1) 26 | err(1, "pledge"); 27 | #endif 28 | xcb_query_pointer_reply_t *pointer; 29 | 30 | uint16_t pointer_x; 31 | uint16_t pointer_y; 32 | 33 | xcb_randr_get_output_info_reply_t *output_info = NULL; 34 | xcb_randr_get_crtc_info_reply_t *output_crtc_info = NULL; 35 | xcb_randr_output_t output; 36 | const char *output_name; 37 | 38 | uint16_t output_w; 39 | uint16_t output_h; 40 | uint16_t output_x; 41 | uint16_t output_y; 42 | 43 | if (argc > 1) 44 | usage(argv[0]); 45 | init_xcb(&conn); 46 | get_screen(conn, &scrn); 47 | 48 | /* Get info about the pointer */ 49 | pointer = xcb_query_pointer_reply(conn, 50 | xcb_query_pointer(conn, scrn->root), NULL); 51 | pointer_x = pointer->root_x; 52 | pointer_y = pointer->root_y; 53 | 54 | /* Iterate through outputs */ 55 | xcb_randr_provider_t *providers; 56 | int p_len = get_providers(conn, scrn, &providers); 57 | 58 | int i = 0; 59 | output_name = NULL; 60 | while (i < p_len && output_name == NULL) { 61 | xcb_randr_output_t *os; 62 | int o_len = get_outputs(conn, providers[i], &os); 63 | 64 | int j = 0; 65 | while (j < o_len && output_name == NULL) { 66 | output = os[j]; 67 | if (get_output_connection(conn, output) == 0) { 68 | /* Check */ 69 | output_info = get_output_info(conn, output); 70 | output_crtc_info = get_output_crtc_info(conn, output_info->crtc); 71 | if (output_crtc_info != NULL) { 72 | output_w = output_crtc_info->width; 73 | output_h = output_crtc_info->height; 74 | output_x = output_crtc_info->x; 75 | output_y = output_crtc_info->y; 76 | 77 | if (pointer_x >= output_x && 78 | pointer_y >= output_y && 79 | pointer_x <= output_x + output_w && 80 | pointer_y <= output_y + output_h) { 81 | 82 | output_name = (const char *)get_output_name(conn, output); 83 | } 84 | } 85 | } 86 | j++; 87 | } 88 | 89 | i++; 90 | } 91 | if (output_name == NULL) 92 | errx(1, "Cannot get output name"); 93 | printf("%s\n", output_name); 94 | free(pointer); 95 | free(output_info); 96 | free(output_crtc_info); 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /ppd.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "randr.h" 9 | #include "util.h" 10 | 11 | xcb_connection_t *conn; 12 | xcb_screen_t *scrn; 13 | 14 | void 15 | usage(char *name) 16 | { 17 | printf("usage: %s \n", name); 18 | exit(0); 19 | } 20 | 21 | int 22 | main(int argc, char *argv[]) 23 | { 24 | #ifdef __OpenBSD__ 25 | if (pledge("stdio rpath unix", NULL) == -1) 26 | err(1, "pledge"); 27 | #endif 28 | xcb_randr_get_output_primary_reply_t *primary_output; 29 | 30 | if (argc > 1) 31 | usage(argv[0]); 32 | init_xcb(&conn); 33 | get_screen(conn, &scrn); 34 | 35 | primary_output = get_primary_output(conn); 36 | 37 | printf("%s\n", get_output_name(conn, primary_output->output)); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /randr.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "util.h" 8 | #include "randr.h" 9 | 10 | int 11 | get_providers(xcb_connection_t * conn, xcb_screen_t * scrn, xcb_randr_provider_t ** ps) 12 | { 13 | xcb_randr_get_providers_cookie_t pc; 14 | pc = xcb_randr_get_providers(conn, scrn->root); 15 | 16 | xcb_randr_get_providers_reply_t *pr; 17 | pr = xcb_randr_get_providers_reply(conn, pc, NULL); 18 | if (!pr) 19 | errx(1, "Could not aquire the array of providers."); 20 | 21 | *ps = xcb_randr_get_providers_providers(pr); 22 | 23 | return xcb_randr_get_providers_providers_length(pr); 24 | } 25 | 26 | int 27 | get_outputs(xcb_connection_t * conn, xcb_randr_provider_t provider, xcb_randr_output_t ** os) 28 | { 29 | xcb_randr_get_provider_info_cookie_t pic; 30 | pic = xcb_randr_get_provider_info(conn, provider, 0); 31 | 32 | xcb_randr_get_provider_info_reply_t *pir; 33 | pir = xcb_randr_get_provider_info_reply(conn, pic, NULL); 34 | if (!pir) 35 | errx(1, "Could not aquire the array of outputs."); 36 | 37 | *os = xcb_randr_get_provider_info_outputs(pir); 38 | return xcb_randr_get_provider_info_outputs_length(pir); 39 | } 40 | 41 | xcb_randr_get_output_info_reply_t * 42 | get_output_info(xcb_connection_t * conn, xcb_randr_output_t output) 43 | { 44 | xcb_randr_get_output_info_cookie_t oic; 45 | 46 | oic = xcb_randr_get_output_info(conn, output, 0); 47 | xcb_randr_get_output_info_reply_t *output_info_reply; 48 | 49 | output_info_reply = xcb_randr_get_output_info_reply(conn, oic, NULL); 50 | if (!output_info_reply) 51 | errx(1, "Could not get output info."); 52 | 53 | return output_info_reply; 54 | } 55 | 56 | uint8_t* 57 | get_output_name(xcb_connection_t * conn, xcb_randr_output_t output) 58 | { 59 | xcb_randr_get_output_info_reply_t *r; 60 | 61 | r = get_output_info(conn, output); 62 | uint8_t *name = xcb_randr_get_output_info_name(r); 63 | int len = xcb_randr_get_output_info_name_length(r); 64 | uint8_t *ret = 65 | malloc(sizeof(uint8_t) * len + 1); 66 | int i; 67 | for (i = 0; i < xcb_randr_get_output_info_name_length(r); i++) { 68 | ret[i] = name[i]; 69 | } 70 | ret[len] = '\0'; 71 | return ret; 72 | } 73 | 74 | int 75 | get_output_connection(xcb_connection_t * conn, xcb_randr_output_t output) 76 | { 77 | xcb_randr_get_output_info_reply_t *r; 78 | r = get_output_info(conn, output); 79 | return r->connection; 80 | } 81 | 82 | xcb_randr_get_crtc_info_reply_t * 83 | get_output_crtc_info(xcb_connection_t * conn, xcb_randr_crtc_t crtc) 84 | { 85 | xcb_randr_get_crtc_info_cookie_t cic; 86 | 87 | cic = xcb_randr_get_crtc_info(conn, crtc, 0); 88 | 89 | xcb_randr_get_crtc_info_reply_t *crtc_info_reply; 90 | crtc_info_reply = xcb_randr_get_crtc_info_reply(conn, cic, NULL); 91 | 92 | return crtc_info_reply; 93 | } 94 | 95 | xcb_window_t 96 | get_focused_window(xcb_connection_t * conn) 97 | { 98 | xcb_window_t win = 0; 99 | xcb_get_input_focus_cookie_t input_focus_cookie; 100 | xcb_get_input_focus_reply_t *input_focus_reply; 101 | 102 | input_focus_cookie = xcb_get_input_focus(conn); 103 | input_focus_reply = xcb_get_input_focus_reply(conn, input_focus_cookie, NULL); 104 | if (!input_focus_reply) 105 | errx(1, "Cannot get focused window."); 106 | win = input_focus_reply->focus; 107 | free(input_focus_reply); 108 | return win; 109 | } 110 | 111 | xcb_get_geometry_reply_t * 112 | get_window_geometry(xcb_connection_t * conn, xcb_window_t window) 113 | { 114 | xcb_get_geometry_cookie_t get_geometry_cookie; 115 | xcb_get_geometry_reply_t *get_geometry_reply; 116 | 117 | get_geometry_cookie = xcb_get_geometry(conn, window); 118 | get_geometry_reply = xcb_get_geometry_reply(conn, get_geometry_cookie, NULL); 119 | 120 | if (!get_geometry_reply) 121 | errx(1, "0x%08x: no such window", window); 122 | return get_geometry_reply; 123 | } 124 | 125 | xcb_randr_get_output_primary_reply_t * 126 | get_primary_output(xcb_connection_t * conn) 127 | { 128 | xcb_screen_t *scrn; 129 | xcb_window_t root; 130 | xcb_randr_get_output_primary_cookie_t c; 131 | xcb_randr_get_output_primary_reply_t *primary_output; 132 | 133 | get_screen(conn, &scrn); 134 | root = scrn->root; 135 | 136 | c = xcb_randr_get_output_primary(conn, root); 137 | primary_output = xcb_randr_get_output_primary_reply(conn, c, NULL); 138 | 139 | return primary_output; 140 | } 141 | -------------------------------------------------------------------------------- /randr.h: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #ifndef RANDR_H__ 4 | #define RANDR_H__ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int get_outputs(xcb_connection_t * conn, xcb_randr_provider_t provider, xcb_randr_output_t ** os); 12 | int get_providers(xcb_connection_t * con, xcb_screen_t * scrn, xcb_randr_provider_t ** ps); 13 | 14 | xcb_randr_get_output_info_reply_t *get_output_info(xcb_connection_t * conn, xcb_randr_output_t output); 15 | uint8_t *get_output_name(xcb_connection_t * conn, xcb_randr_output_t output); 16 | int get_output_connection(xcb_connection_t * conn, xcb_randr_output_t output); 17 | 18 | xcb_randr_get_crtc_info_reply_t *get_output_crtc_info(xcb_connection_t * conn, xcb_randr_crtc_t crtc); 19 | xcb_window_t get_focused_window(xcb_connection_t * conn); 20 | xcb_get_geometry_reply_t *get_window_geometry(xcb_connection_t * conn, xcb_window_t window); 21 | xcb_randr_get_output_primary_reply_t *get_primary_output(xcb_connection_t * conn); 22 | 23 | #endif 24 | /* end of include guard: WMUTILS_RANDR */ 25 | -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "util.h" 8 | 9 | void 10 | init_xcb(xcb_connection_t ** con) 11 | { 12 | *con = xcb_connect(NULL, NULL); 13 | if (xcb_connection_has_error(*con)) 14 | errx(1, "unable connect to the X server"); 15 | } 16 | 17 | void 18 | kill_xcb(xcb_connection_t ** con) 19 | { 20 | if (*con) 21 | xcb_disconnect(*con); 22 | } 23 | 24 | void 25 | get_screen(xcb_connection_t * con, xcb_screen_t ** scr) 26 | { 27 | *scr = xcb_setup_roots_iterator(xcb_get_setup(con)).data; 28 | if (*scr == NULL) 29 | errx(1, "unable to retrieve screen informations"); 30 | } 31 | -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #ifndef UTIL_H__ 4 | #define UTIL_H__ 5 | 6 | void init_xcb (xcb_connection_t **); 7 | void kill_xcb (xcb_connection_t **); 8 | 9 | void get_screen(xcb_connection_t *, xcb_screen_t **); 10 | 11 | #endif 12 | --------------------------------------------------------------------------------