drm/tests/modefb/demo.c

177 lines
3.8 KiB
C
Raw Normal View History

2008-01-27 19:12:29 -07:00
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include "linux/fb.h"
#include "sys/ioctl.h"
2008-01-30 07:47:26 -07:00
#include "xf86drm.h"
#include "xf86drmMode.h"
2008-01-27 19:12:29 -07:00
2008-01-30 07:47:26 -07:00
void pretty(int fd);
2008-01-27 19:12:29 -07:00
void setMode(struct fb_var_screeninfo *var);
void pan(int fd, struct fb_var_screeninfo *var, int x, int y);
2008-01-30 07:47:26 -07:00
void cursor(int fd, int drmfd);
void prettyCursor(int fd, unsigned int handle, unsigned int color);
extern void sleep(int);
2008-01-27 19:12:29 -07:00
int main(int argc, char **argv)
{
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
2008-01-30 07:47:26 -07:00
const char* driver = "i915";
2008-01-27 19:12:29 -07:00
const char* name = "/dev/fb0";
int fd = open(name, O_RDONLY);
2008-01-30 07:47:26 -07:00
int drmfd = drmOpen(driver, NULL);
2008-01-27 19:12:29 -07:00
if (fd == -1) {
printf("open %s : %s\n", name, strerror(errno));
return 1;
}
2008-01-30 07:47:26 -07:00
if (drmfd < 0) {
printf("drmOpen failed\n");
return 1;
}
2008-01-27 19:12:29 -07:00
memset(&var, 0, sizeof(struct fb_var_screeninfo));
memset(&fix, 0, sizeof(struct fb_fix_screeninfo));
if (ioctl(fd, FBIOGET_VSCREENINFO, &var))
printf("var %s\n", strerror(errno));
if (ioctl(fd, FBIOGET_FSCREENINFO, &fix))
printf("fix %s\n", strerror(errno));
setMode(&var);
printf("pan: 0, 0\n");
pan(fd, &var, 0, 0);
sleep(2);
printf("pan: 100, 0\n");
pan(fd, &var, 100, 0);
sleep(2);
printf("pan: 0, 100\n");
pan(fd, &var, 0, 100);
sleep(2);
printf("pan: 100, 100\n");
pan(fd, &var, 100, 100);
sleep(2);
printf("pan: 0, 0\n");
pan(fd, &var, 0, 0);
sleep(2);
printf("cursor\n");
2008-01-30 07:47:26 -07:00
cursor(fd, drmfd);
2008-01-27 19:12:29 -07:00
return 0;
}
void pan(int fd, struct fb_var_screeninfo *var, int x, int y)
{
var->xoffset = x;
var->yoffset = y;
var->activate = FB_ACTIVATE_NOW;
if (ioctl(fd, FBIOPUT_VSCREENINFO, var))
printf("pan error: %s\n", strerror(errno));
}
/*
2008-01-30 07:47:26 -07:00
* Cursor support removed from the fb kernel interface
* using drm instead.
2008-01-27 19:12:29 -07:00
*/
2008-01-30 07:47:26 -07:00
void cursor(int fd, int drmfd)
2008-01-27 19:12:29 -07:00
{
2008-01-30 07:47:26 -07:00
drmModeResPtr res = drmModeGetResources(drmfd);
uint32_t crtc = res->crtcs[1]; /* select crtc here */
drmBO bo;
int ret;
ret = drmBOCreate(drmfd, 64 * 64 * 4, 0, 0,
DRM_BO_FLAG_READ |
DRM_BO_FLAG_WRITE |
DRM_BO_FLAG_MEM_VRAM |
DRM_BO_FLAG_NO_EVICT,
DRM_BO_HINT_DONT_FENCE, &bo);
if (ret) {
printf("failed to create buffer: %s\n", strerror(ret));
return;
}
2008-01-27 19:12:29 -07:00
2008-01-30 07:47:26 -07:00
prettyCursor(drmfd, bo.handle, 0xFFFF00FF);
drmModeSetCursor(drmfd, crtc, &bo, 64, 64);
drmModeMoveCursor(drmfd, crtc, 0, 0);
sleep(2);
drmModeMoveCursor(drmfd, crtc, 40, 40);
prettyCursor(drmfd, bo.handle, 0xFFFF0000);
2008-01-27 19:12:29 -07:00
sleep(2);
2008-01-30 07:47:26 -07:00
drmModeSetCursor(drmfd, crtc, 0, 0, 0);
drmBOUnreference(drmfd, &bo);
}
void prettyCursor(int drmfd, unsigned int handle, unsigned int color)
{
drmBO bo;
unsigned int *ptr;
int i;
2008-01-27 19:12:29 -07:00
2008-01-30 07:47:26 -07:00
drmBOReference(drmfd, handle, &bo);
drmBOMap(drmfd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, (void**)&ptr);
2008-01-27 19:12:29 -07:00
2008-01-30 07:47:26 -07:00
for (i = 0; i < (64 * 64); i++)
ptr[i] = color;
2008-01-27 19:12:29 -07:00
2008-01-30 07:47:26 -07:00
drmBOUnmap(drmfd, &bo);
drmBOUnreference(drmfd, &bo);
2008-01-27 19:12:29 -07:00
}
struct drm_mode
{
int clock;
int hdisplay;
int hsync_start;
int hsync_end;
int htotal;
int hskew;
int vdisplay;
int vsync_start;
int vsync_end;
int vtotal;
int vscan;
int vrefresh;
int flags;
};
struct drm_mode mode =
{
.clock = 25200,
.hdisplay = 640,
.hsync_start = 656,
.hsync_end = 752,
.htotal = 800,
.hskew = 0,
.vdisplay = 480,
.vsync_start = 490,
.vsync_end = 492,
.vtotal = 525,
.vscan = 0,
.vrefresh = 60000, /* vertical refresh * 1000 */
.flags = 10,
};
void setMode(struct fb_var_screeninfo *var) {
var->activate = FB_ACTIVATE_NOW;
var->xres = mode.hdisplay;
var->right_margin = mode.hsync_start - mode.hdisplay;
var->hsync_len = mode.hsync_end - mode.hsync_start;
var->left_margin = mode.htotal - mode.hsync_end;
var->yres = mode.vdisplay;
var->lower_margin = mode.vsync_start - mode.vdisplay;
var->vsync_len = mode.vsync_end - mode.vsync_start;
var->upper_margin = mode.vtotal - mode.vsync_end;
var->pixclock = 10000000 / mode.htotal * 1000 / mode.vtotal * 100;
/* avoid overflow */
var->pixclock = var->pixclock * 1000 / mode.vrefresh;
}