modeset.c revision 72c0a2c255b172ebbb2a2b7dab7c9aec4c9582d9
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
/*
* Modeset Testing
* The modeset tool attaches to the session of the caller and shows a
* test-pattern on all displays of this session. It is meant as debugging tool
* for the grdev infrastructure.
*/
#include <drm_fourcc.h>
#include <errno.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include "sd-bus.h"
#include "sd-event.h"
#include "sd-login.h"
#include "build.h"
#include "macro.h"
#include "random-util.h"
#include "signal-util.h"
#include "util.h"
#include "grdev.h"
#include "sysview.h"
struct Modeset {
char *session;
char *seat;
uint8_t r, g, b;
bool my_tty : 1;
bool managed : 1;
};
if (m->grdev_session)
return 0;
}
if (!m)
return NULL;
free(m);
return NULL;
}
unsigned int vtnr;
long mode;
int r;
/* Using logind's Controller API is highly fragile if there is already
* a session controller running. If it is registered as controller
* itself, TakeControl will simply fail. But if its a legacy controller
* that does not use logind's controller API, we must never register
* our own controller. Otherwise, we really mess up the VT. Therefore,
* only run in managed mode if there's no-one else. Furthermore, never
* try to access graphics devices if there's someone else. Unlike input
* devices, graphics devies cannot be shared easily. */
if (!isatty(1))
return false;
if (!session)
return false;
return false;
mode = 0;
return false;
return false;
return true;
}
int r;
if (!m)
return log_oom();
if (r < 0)
return log_error_errno(r, "Cannot retrieve logind session: %m");
if (r < 0)
return log_error_errno(r, "Cannot retrieve seat of logind session: %m");
m->r = rand() % 0xff;
m->g = rand() % 0xff;
m->b = rand() % 0xff;
r = sd_event_default(&m->event);
if (r < 0)
return r;
r = sd_bus_open_system(&m->bus);
if (r < 0)
return r;
if (r < 0)
return r;
if (r < 0)
return r;
if (r < 0)
return r;
if (r < 0)
return r;
if (r < 0)
return r;
/* schedule before sd-bus close */
if (r < 0)
return r;
r = sysview_context_new(&m->sysview,
m->event,
m->bus,
NULL);
if (r < 0)
return r;
if (r < 0)
return r;
*out = m;
m = NULL;
return 0;
}
/* generate smoothly morphing colors */
}
return next;
}
uint32_t j, k, *b;
uint8_t *l;
for (j = 0; j < t->height; ++j) {
for (k = 0; k < t->width; ++k) {
b = (uint32_t*)l;
b[k] = (0xff << 24) | (m->r << 16) | (m->g << 8) | m->b;
}
}
}
const grdev_display_target *t;
GRDEV_DISPLAY_FOREACH_TARGET(d, t) {
modeset_draw(m, t);
grdev_display_flip_target(d, t);
}
}
case GRDEV_EVENT_DISPLAY_ADD:
break;
break;
break;
break;
}
}
sysview_device *d;
const char *name;
int r;
return 1;
break;
assert(!m->grdev_session);
flags = 0;
if (m->managed)
r = grdev_session_new(&m->grdev_session,
m->grdev,
name,
m);
if (r < 0)
return log_error_errno(r, "Cannot create grdev session: %m");
if (m->managed) {
if (r < 0)
return log_error_errno(r, "Cannot request session control: %m");
}
break;
if (!m->grdev_session)
return 0;
sd_event_exit(m->event, 0);
break;
type = sysview_device_get_type(d);
if (type == SYSVIEW_DEVICE_DRM)
break;
type = sysview_device_get_type(d);
if (type == SYSVIEW_DEVICE_DRM)
break;
type = sysview_device_get_type(d);
if (type == SYSVIEW_DEVICE_DRM)
break;
if (r < 0)
return log_error_errno(r, "Cannot acquire session control: %m");
if (r < 0)
break;
}
return 0;
}
static int modeset_run(Modeset *m) {
int r;
assert(m);
if (!m->my_tty) {
log_warning("You need to run this program on a free VT");
return -EACCES;
}
log_warning("You run in unmanaged mode without being root. This is likely to fail..");
printf("modeset - Show test pattern on selected graphics devices\n"
" Running on seat '%s' in user-session '%s'\n"
" Exit by pressing ^C\n\n",
if (r < 0)
goto out;
if (r < 0) {
r = -errno;
goto out;
}
if (r < 0) {
r = -errno;
goto out;
}
r = sd_event_loop(m->event);
printf("exiting..\n");
out:
return r;
}
static int help(void) {
printf("%s [OPTIONS...]\n\n"
"Show test pattern on all selected graphics devices.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
return 0;
}
enum {
ARG_VERSION = 0x100,
};
{},
};
int c;
switch (c) {
case 'h':
help();
return 0;
case ARG_VERSION:
return 0;
case '?':
return -EINVAL;
default:
assert_not_reached("Unhandled option");
}
log_error("Too many arguments");
return -EINVAL;
}
return 1;
}
int r;
log_open();
if (r <= 0)
goto finish;
r = modeset_new(&m);
if (r < 0)
goto finish;
r = modeset_run(m);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}