Skip to content

Commit

Permalink
[new] x_util: functions and data structures for x server information
Browse files Browse the repository at this point in the history
Get X display info from xrandr and xdpyinfo

Signed-off-by: Burt P <pburt0@gmail.com>
  • Loading branch information
bp0 committed Mar 18, 2018
1 parent 1518923 commit 12d41a8
Show file tree
Hide file tree
Showing 3 changed files with 280 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Expand Up @@ -227,6 +227,7 @@ add_executable(hardinfo
hardinfo/cpu_util.c
hardinfo/dmi_util.c
hardinfo/dt_util.c
hardinfo/x_util.c
shell/callbacks.c
shell/iconcache.c
shell/menu.c
Expand Down Expand Up @@ -257,6 +258,7 @@ add_executable(hardinfo
hardinfo/cpu_util.c
hardinfo/dmi_util.c
hardinfo/dt_util.c
hardinfo/x_util.c
shell/callbacks.c
shell/iconcache.c
shell/menu.c
Expand Down
200 changes: 200 additions & 0 deletions hardinfo/x_util.c
@@ -0,0 +1,200 @@
/*
* HardInfo - Displays System Information
* Copyright (C) 2003-2017 Leandro A. F. Pereira <leandro@hardinfo.org>
* This file
* Copyright (C) 2018 Burt P. <pburt0@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "hardinfo.h"
#include "x_util.h"

/* get x information from xrandr and xdpyinfo */

static char *xdpy_line_value(char *line, const char *prefix) {
if (g_str_has_prefix(line, prefix)) {
line += strlen(prefix) + 1;
return g_strstrip(line);
} else
return NULL;
}

gboolean fill_xi_info(xi_info *xi) {
gboolean spawned;
gchar *out, *err, *p, *l, *t, *next_nl;
gchar *xi_cmd = g_strdup("xdpyinfo");

int ec;

spawned = g_spawn_command_line_sync(xi_cmd,
&out, &err, NULL, NULL);
g_free(xi_cmd);
if (spawned) {
p = out;
while(next_nl = strchr(p, '\n')) {
strend(p, '\n');
g_strstrip(p);
if (l = xdpy_line_value(p, "name of display")) {
xi->display_name = g_strdup(l);
goto xi_next_line;
}
if (l = xdpy_line_value(p, "vendor string")) {
xi->vendor = g_strdup(l);
goto xi_next_line;
}
if (l = xdpy_line_value(p, "vendor release number")) {
xi->release_number = g_strdup(l);
if (xi->version) free(xi->version);
xi->version = g_strdup(l + 1);
goto xi_next_line;
}
if (l = xdpy_line_value(p, "XFree86 version")) {
if (xi->version) free(xi->version);
xi->version = g_strdup(l);
goto xi_next_line;
}
if (l = xdpy_line_value(p, "X.Org version")) {
if (xi->version) free(xi->version);
xi->version = g_strdup(l);
goto xi_next_line;
}

xi_next_line:
p = next_nl + 1;
}
g_free(out);
g_free(err);
return TRUE;
}
return FALSE;
}

xi_info *xi_get_info() {
xi_info *xi = malloc(sizeof(xi_info));
memset(xi, 0, sizeof(xi_info));
fill_xi_info(xi);
return xi;
}

void xi_free(xi_info *xi) {
if (xi) {
free(xi->display_name);
free(xi->vendor);
free(xi->version);
free(xi);
}
}

gboolean fill_xrr_info(xrr_info *xrr) {
gboolean spawned;
gchar *out, *err, *p, *l, *t, *next_nl;
gchar *xrr_cmd = g_strdup("xrandr");

int ec, is_output;
x_screen ts;
x_output to;
char buff[128];
char alist[512];

memset(&ts, 0, sizeof(x_screen));
memset(&to, 0, sizeof(x_output));
memset(buff, 0, 128);

spawned = g_spawn_command_line_sync(xrr_cmd,
&out, &err, NULL, NULL);
g_free(xrr_cmd);
if (spawned) {
p = out;
while(next_nl = strchr(p, '\n')) {
strend(p, '\n');
g_strstrip(p);

ec = sscanf(p, "Screen %d: minimum %d x %d, current %d x %d, maximum %d x %d",
&ts.number,
&ts.min_px_width, &ts.min_px_height,
&ts.px_width, &ts.px_height,
&ts.max_px_width, &ts.max_px_height);
if (ec == 7) {
/* new screen */
xrr->screen_count++;
if (xrr->screens == NULL)
xrr->screens = malloc(xrr->screen_count * sizeof(x_screen));
else
xrr->screens = realloc(xrr->screens, xrr->screen_count * sizeof(x_screen));
memcpy(&xrr->screens[xrr->screen_count-1], &ts, sizeof(x_screen));
memset(&ts, 0, sizeof(x_screen)); /* clear the temp */
goto xrr_next_line;
}

is_output = 0;
ec = sscanf(p, "%s disconnected (%s)", buff, alist);
if (ec == 2) {
/* new disconnected output */
to.screen = xrr->screen_count - 1;
to.connected = 0;
is_output = 1;
}
ec = sscanf(p, "%s connected (%s)", buff, alist);
if (ec == 2) {
/* new connected, but unused output */
to.screen = -1;
to.connected = 1;
is_output = 1;
}
ec = sscanf(p, "%s connected %dx%d+%d+%d", buff, &to.px_width, &to.px_height, &to.px_offset_x, &to.px_offset_y);
if (ec == 5) {
/* new connected output */
to.screen = xrr->screen_count - 1;
to.connected = 1;
is_output = 1;
}
if (is_output) {
strncpy(to.name, buff, 63);
xrr->output_count++;
if (xrr->outputs == NULL)
xrr->outputs = malloc(xrr->output_count * sizeof(x_output));
else
xrr->outputs = realloc(xrr->outputs, xrr->output_count * sizeof(x_output));
memcpy(&xrr->outputs[xrr->output_count-1], &to, sizeof(x_output));
memset(&to, 0, sizeof(x_output)); /* clear the temp */
goto xrr_next_line;
}

xrr_next_line:
p = next_nl + 1;
}
g_free(out);
g_free(err);
return TRUE;
}
return FALSE;
}

xrr_info *xrr_get_info() {
xrr_info *xrr = malloc(sizeof(xrr_info));
memset(xrr, 0, sizeof(xrr_info));

xrr->xi = xi_get_info();
fill_xrr_info(xrr);

return xrr;
}

void xrr_free(xrr_info *xrr) {
if (xrr) {
xi_free(xrr->xi);
free(xrr);
}
}
78 changes: 78 additions & 0 deletions includes/x_util.h
@@ -0,0 +1,78 @@
/*
* HardInfo - Displays System Information
* Copyright (C) 2003-2017 Leandro A. F. Pereira <leandro@hardinfo.org>
* This file
* Copyright (C) 2017 Burt P. <pburt0@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef __X_UTIL_H__
#define __X_UTIL_H__

typedef struct {
char *display_name, *vendor, *version, *release_number;
} xi_info;

xi_info *xi_get_info();
void xi_free(xi_info *xi);

typedef struct {
int number;
int px_width;
int px_height;
int min_px_width;
int min_px_height;
int max_px_width;
int max_px_height;
} x_screen;

typedef struct {
/* I guess it is kindof like gpu? */
int reserved; /* TODO: */
} x_provider;

typedef struct {
char name[64];
int connected;
int screen; /* index into xrr_info.screens[], look there for x screen number */
int px_width;
int px_height;
int px_offset_x;
int px_offset_y;
int mm_width;
int mm_height;
} x_output;

typedef struct {
int reserved; /* TODO: */
} x_monitor;

typedef struct {
xi_info *xi;
char *display_name;
int screen_count;
x_screen *screens;
int provider_count;
x_provider *providers;
int output_count;
x_output *outputs;
int monitor_count;
x_monitor *monitors;
} xrr_info;

xrr_info *xrr_get_info();
void xrr_free(xrr_info *xrr);

#endif

0 comments on commit 12d41a8

Please sign in to comment.