Commit 06ac2055 authored by Jeremy White's avatar Jeremy White

Further progress on basic spice integraton.

parent 95db2b9e
......@@ -3,6 +3,7 @@ AM_INIT_AUTOMAKE
PKG_CHECK_MODULES(X11, x11)
PKG_CHECK_MODULES(XDAMAGE, xdamage)
PKG_CHECK_MODULES(XEXT, xext)
PKG_CHECK_MODULES(GTK2, gtk+-2.0)
PKG_CHECK_MODULES(SPICE, spice-server)
PKG_CHECK_MODULES(GLIB2, glib-2.0)
......
bin_PROGRAMS = x11spice
AM_CFLAGS = -Wall $(XLL_CFLAGS) $(GTK2_CFLAGS) $(SPICE_CFLAGS) $(GLIB2_CFLAGS) $(XDAMAGE_CFLAGS)
x11spice_LDADD = $(X11_LIBS) $(GTK2_LIBS) $(SPICE_LIBS) $(GLIB2_LIBS) $(XDAMAGE_LIBS)
AM_CFLAGS = -Wall $(X11_CFLAGS) $(GTK2_CFLAGS) $(SPICE_CFLAGS) $(GLIB2_CFLAGS) $(XDAMAGE_CFLAGS) $(XEXT_CFLAGS)
x11spice_LDADD = $(X11_LIBS) $(GTK2_LIBS) $(SPICE_LIBS) $(GLIB2_LIBS) $(XDAMAGE_LIBS) $(XEXT_LIBS)
x11spice_SOURCES = \
display.c \
gui.c \
......
......@@ -22,7 +22,12 @@
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <glib.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include "x11spice.h"
#include "options.h"
......@@ -45,6 +50,12 @@ int display_open(display_t *d, options_t *options)
return X11SPICE_ERR_NODAMAGE;
}
if (! XShmQueryExtension(d->xdisplay))
{
fprintf(stderr, "Error: XSHM not found on display %s\n", options->display ? options->display : "");
return X11SPICE_ERR_NOSHM;
}
d->xdamage = XDamageCreate(d->xdisplay, DefaultRootWindow(d->xdisplay), XDamageReportRawRectangles);
g_info("Display %s opened", options->display ? options->display : "");
......@@ -52,6 +63,66 @@ int display_open(display_t *d, options_t *options)
return 0;
}
int create_shm_image(display_t *d, shm_image_t *shmi, int w, int h)
{
int scr = DefaultScreen(d->xdisplay);
int imgsize;
shmi->img = XShmCreateImage(d->xdisplay,
DefaultVisual(d->xdisplay, scr),
DefaultDepth(d->xdisplay, scr),
ZPixmap /* FIXME - format we want? */, NULL /* data? */,
&shmi->info,
w ? w : DisplayWidth(d->xdisplay, scr),
h ? h : DisplayHeight(d->xdisplay, scr));
if (! shmi->img)
return X11SPICE_ERR_NOSHM;
imgsize = shmi->img->bytes_per_line * shmi->img->height;
shmi->info.shmid = shmget(IPC_PRIVATE, imgsize, IPC_CREAT | 0700);
if (shmi->info.shmid == -1)
{
g_error("Cannot get shared memory of size %d", imgsize);
XDestroyImage(shmi->img);
return X11SPICE_ERR_NOSHM;
}
shmi->info.shmaddr = shmi->img->data = shmat(shmi->info.shmid, 0, 0);
shmi->info.readOnly = False;
if (!XShmAttach(d->xdisplay, &shmi->info))
{
g_error("Failed to attach shared memory");
shmdt(shmi->info.shmaddr);
shmctl(shmi->info.shmid, IPC_RMID, NULL);
XDestroyImage(shmi->img);
return X11SPICE_ERR_NOSHM;
}
return 0;
}
int read_shm_image(display_t *d, shm_image_t *shmi, int x, int y)
{
if (!XShmGetImage(d->xdisplay, DefaultRootWindow(d->xdisplay), shmi->img,
x, y, AllPlanes))
{
g_error("XShmGetImage from %dx%d into size %dx%d failed",
x, y, shmi->img->width, shmi->img->height);
return X11SPICE_ERR_NOSHM;
}
return 0;
}
void destroy_shm_image(display_t *d, shm_image_t *shmi)
{
XShmDetach(d->xdisplay, &shmi->info);
shmdt(shmi->info.shmaddr);
shmctl(shmi->info.shmid, IPC_RMID, NULL);
XDestroyImage(shmi->img);
}
void display_close(display_t *d)
{
XDamageDestroy(d->xdisplay, d->xdamage);
......
......@@ -23,16 +23,24 @@
#include <X11/Xlib.h>
#include <X11/extensions/Xdamage.h>
#include <X11/extensions/XShm.h>
/*----------------------------------------------------------------------------
** Structure definitions
**--------------------------------------------------------------------------*/
typedef struct
{
XImage *img;
XShmSegmentInfo info;
}shm_image_t;
typedef struct
{
Display *xdisplay;
Damage xdamage;
int xd_event_base;
int xd_error_base;
shm_image_t fullscreen;
} display_t;
......@@ -41,5 +49,8 @@ typedef struct
**--------------------------------------------------------------------------*/
int display_open(display_t *display, options_t *options);
void display_close(display_t *display);
int create_shm_image(display_t *d, shm_image_t *shmi, int w, int h);
int read_shm_image(display_t *d, shm_image_t *shmi, int x, int y);
void destroy_shm_image(display_t *d, shm_image_t *shmi);
#endif
......@@ -18,9 +18,37 @@
along with x11spice. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
#include <X11/Xutil.h>
#include "x11spice.h"
#include "session.h"
static void save_ximage_pnm(XImage *img)
{
int x,y;
unsigned long pixel;
static int count = 0;
char fname[200];
FILE *fp;
sprintf(fname, "ximage%04d.ppm", count++);
fp = fopen(fname, "w");
fprintf(fp,"P3\n%d %d\n255\n",img->width, img->height);
for (y=0; y<img->height; y++)
{
for (x=0; x<img->width; x++)
{
pixel=XGetPixel(img,x,y);
fprintf(fp,"%ld %ld %ld\n",
pixel>>16,(pixel&0x00ff00)>>8,pixel&0x0000ff);
}
}
fclose(fp);
}
static void session_handle_xevent(int fd, int event, void *opaque)
{
session_t *s = (session_t *) opaque;
......@@ -31,6 +59,8 @@ static void session_handle_xevent(int fd, int event, void *opaque)
rc = XNextEvent(s->display.xdisplay, &xev);
if (rc == 0)
{
shm_image_t shmi;
if (xev.type != s->display.xd_event_base + XDamageNotify)
{
g_debug("Unexpected X event %d", xev.type);
......@@ -41,11 +71,53 @@ static void session_handle_xevent(int fd, int event, void *opaque)
dev->serial, dev->send_event, dev->level, dev->more,
dev->area.width, dev->area.height, dev->area.x, dev->area.y,
dev->geometry.width, dev->geometry.height, dev->geometry.x, dev->geometry.y);
if (create_shm_image(&s->display, &shmi, dev->area.width, dev->area.height) == 0)
{
if (read_shm_image(&s->display, &shmi, dev->area.x, dev->area.y) == 0)
{
//save_ximage_pnm(shmi.img);
spice_qxl_wakeup(&s->spice.display_sin);
}
destroy_shm_image(&s->display, &shmi);
}
}
}
static int create_primary(session_t *s)
{
int rc;
int scr = DefaultScreen(s->display.xdisplay);
QXLDevSurfaceCreate surface;
rc = create_shm_image(&s->display, &s->display.fullscreen, 0, 0);
if (rc)
return rc;
memset(&surface, 0, sizeof(surface));
surface.height = DisplayHeight(s->display.xdisplay, scr);
surface.width = DisplayWidth(s->display.xdisplay, scr);
surface.stride = -s->display.fullscreen.img->bytes_per_line;
surface.type = QXL_SURF_TYPE_PRIMARY;
surface.flags = 0;
surface.group_id = 0;
surface.mouse_mode = TRUE;
// Position appears to be completely unused
surface.position = 0;
// FIXME - compute this dynamically?
surface.format = SPICE_SURFACE_FMT_32_xRGB;
surface.mem = (QXLPHYSICAL) s->display.fullscreen.img->data;
spice_qxl_create_primary_surface(&s->spice.display_sin, 0, &surface);
return 0;
}
int session_start(session_t *s)
{
int rc;
s->xwatch = s->spice.core->watch_add(ConnectionNumber(s->display.xdisplay),
SPICE_WATCH_EVENT_READ, session_handle_xevent, s);
if (! s->xwatch)
......@@ -56,6 +128,10 @@ int session_start(session_t *s)
// FIXME - not sure I know why...
XPending(s->display.xdisplay);
rc = create_primary(s);
if (rc)
return rc;
return 0;
}
......
......@@ -20,6 +20,7 @@
#include <glib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "local_spice.h"
......@@ -168,13 +169,23 @@ static void attach_worker(QXLInstance *qin, QXLWorker *qxl_worker)
static int count = 0;
spice_t *s = SPICE_CONTAINEROF(qin, spice_t, display_sin);
static QXLDevMemSlot slot = {
.slot_group_id = 0,
.slot_id = 0,
.generation = 0,
.virt_start = 0,
.virt_end = ~0,
.addr_delta = 0,
.qxl_ram_size = ~0,
};
if (++count > 1)
{
g_info("Ignoring worker %d", count);
return;
}
// FIXME - spice_qxl_add_memslot(qin, &slot);
spice_qxl_add_memslot(qin, &slot);
// FIXME - do we ever need the worker?
s->worker = qxl_worker;
}
......@@ -208,11 +219,13 @@ static void get_init_info(QXLInstance *qin, QXLDevInitInfo *info)
static int get_command(QXLInstance *qin, struct QXLCommandExt *cmd)
{
g_debug("FIXME! UNIMPLEMENTED! %s", __func__);
return 0;
}
static int req_cmd_notification(QXLInstance *qin)
{
g_debug("FIXME! UNIMPLEMENTED! %s", __func__);
return 1;
}
static void release_resource(QXLInstance *qin, struct QXLReleaseInfoExt release_info)
......@@ -223,11 +236,13 @@ static void release_resource(QXLInstance *qin, struct QXLReleaseInfoExt release_
static int get_cursor_command(QXLInstance *qin, struct QXLCommandExt *cmd)
{
g_debug("FIXME! UNIMPLEMENTED! %s", __func__);
return 0;
}
static int req_cursor_notification(QXLInstance *qin)
{
g_debug("FIXME! UNIMPLEMENTED! %s", __func__);
return 1;
}
static void notify_update(QXLInstance *qin, uint32_t update_id)
......@@ -238,6 +253,8 @@ static void notify_update(QXLInstance *qin, uint32_t update_id)
static int flush_resources(QXLInstance *qin)
{
g_debug("FIXME! UNIMPLEMENTED! %s", __func__);
// Return 0 to direct the server to flush resources
return 1;
}
static void async_complete(QXLInstance *qin, uint64_t cookie)
......@@ -254,7 +271,7 @@ static void update_area_complete(QXLInstance *qin, uint32_t surface_id,
static void set_client_capabilities(QXLInstance *qin,
uint8_t client_present,
uint8_t caps[SPICE_CAPABILITIES_SIZE])
uint8_t *caps)
{
g_debug("FIXME! UNIMPLEMENTED! %s", __func__);
}
......@@ -263,6 +280,7 @@ static int client_monitors_config(QXLInstance *qin,
VDAgentMonitorsConfig *monitors_config)
{
g_debug("FIXME! UNIMPLEMENTED! %s", __func__);
return FALSE;
}
void initialize_spice_instance(spice_t *s)
......@@ -354,6 +372,8 @@ int spice_start(spice_t *s, options_t *options)
return X11SPICE_ERR_SPICE_INIT_FAILED;
}
spice_server_vm_start(s->server);
return 0;
}
......
......@@ -30,5 +30,6 @@
#define X11SPICE_ERR_SPICE_INIT_FAILED 4
#define X11SPICE_ERR_NODAMAGE 5
#define X11SPICE_ERR_NOWATCH 6
#define X11SPICE_ERR_NOSHM 6
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment