--- /dev/null
+/* $Id$
+
+This file is part of libmspgbase
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef WIN32
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/Xutil.h>
+#endif
+#include <msp/core/except.h>
+#include "display.h"
+#include "drawcontext.h"
+#include "window.h"
+
+namespace Msp {
+namespace Graphics {
+
+DrawContext::DrawContext(Window &w):
+ display(w.get_display()),
+ window(w),
+ image(0)
+{
+#ifndef WIN32
+ ::Display *dpy=display.get_display();
+
+ use_shm=false; XShmQueryExtension(dpy);
+
+ XWindowAttributes wa;
+ XGetWindowAttributes(dpy, window.get_handle(), &wa);
+
+ if(use_shm)
+ {
+ image=XShmCreateImage(dpy, wa.visual, wa.depth, ZPixmap, 0, &shminfo, wa.width, wa.height);
+ if(!image)
+ throw Exception("Could not create shared memory XImage");
+
+ shminfo.shmid=shmget(IPC_PRIVATE, image->bytes_per_line*image->height, IPC_CREAT|0666);
+ shminfo.shmaddr=image->data=reinterpret_cast<char *>(shmat(shminfo.shmid, 0, 0));
+ shminfo.readOnly=false;
+
+ XShmAttach(dpy, &shminfo);
+
+ XSync(dpy, false);
+ display.check_error();
+ }
+ else
+ {
+ image=XCreateImage(dpy, wa.visual, wa.depth, ZPixmap, 0, 0, wa.width, wa.height, 8, 0);
+ if(!image)
+ throw Exception("Could not create XImage");
+ image->data=new char[image->bytes_per_line*image->height];
+ }
+#endif
+}
+
+DrawContext::~DrawContext()
+{
+#ifndef WIN32
+ if(use_shm)
+ {
+ XShmDetach(display.get_display(), &shminfo);
+ shmdt(shminfo.shmaddr);
+ shmctl(shminfo.shmid, IPC_RMID, 0);
+ }
+
+ XDestroyImage(image);
+#endif
+}
+
+void DrawContext::update()
+{
+#ifndef WIN32
+ ::Display *dpy=display.get_display();
+
+ GC gc=XCreateGC(dpy, window.get_handle(), 0, 0);
+
+ if(use_shm)
+ XShmPutImage(dpy, window.get_handle(), gc, image, 0, 0, 0, 0, image->width, image->height, false);
+ else
+ XPutImage(dpy, window.get_handle(), gc, image, 0, 0, 0, 0, image->width, image->height);
+
+ XFreeGC(dpy, gc);
+#endif
+}
+
+} // namespace Graphics
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspgbase
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GBASE_DRAWCONTEXT_H_
+#define MSP_GBASE_DRAWCONTEXT_H_
+
+#ifndef WIN32
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+#endif
+
+namespace Msp {
+namespace Graphics {
+
+class Display;
+class Window;
+
+class DrawContext
+{
+private:
+ Display &display;
+ Window &window;
+#ifndef WIN32
+ XImage *image;
+ bool use_shm;
+ XShmSegmentInfo shminfo;
+#endif
+
+public:
+ DrawContext(Window &);
+ ~DrawContext();
+
+ Window &get_window() const { return window; }
+ unsigned get_depth() const { return image->depth; }
+ unsigned char *get_data() { return reinterpret_cast<unsigned char *>(image->data); }
+ void update();
+};
+
+} // namespace Graphics
+} // namespace Msp
+
+#endif