]> git.tdb.fi Git - libs/gui.git/blob - source/gbase/drawcontext.cpp
OpenGL can now be required as a package on all archs
[libs/gui.git] / source / gbase / drawcontext.cpp
1 /* $Id$
2
3 This file is part of libmspgbase
4 Copyright © 2007 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #ifndef WIN32
9 #include <sys/ipc.h>
10 #include <sys/shm.h>
11 #include <X11/Xutil.h>
12 #endif
13 #include <msp/core/except.h>
14 #include "display.h"
15 #include "drawcontext.h"
16 #include "window.h"
17
18 namespace Msp {
19 namespace Graphics {
20
21 DrawContext::DrawContext(Window &w):
22         display(w.get_display()),
23         window(w)
24 {
25 #ifndef WIN32
26         ::Display *dpy=display.get_display();
27
28         use_shm=XShmQueryExtension(dpy);
29
30         XWindowAttributes wa;
31         XGetWindowAttributes(dpy, window.get_handle(), &wa);
32
33         if(use_shm)
34         {
35                 image=XShmCreateImage(dpy, wa.visual, wa.depth, ZPixmap, 0, &shminfo, wa.width, wa.height);
36                 if(!image)
37                         throw Exception("Could not create shared memory XImage");
38
39                 shminfo.shmid=shmget(IPC_PRIVATE, image->bytes_per_line*image->height, IPC_CREAT|0666);
40                 shminfo.shmaddr=image->data=reinterpret_cast<char *>(shmat(shminfo.shmid, 0, 0));
41                 shminfo.readOnly=false;
42
43                 XShmAttach(dpy, &shminfo);
44
45                 XSync(dpy, false);
46                 display.check_error();
47         }
48         else
49         {
50                 image=XCreateImage(dpy, wa.visual, wa.depth, ZPixmap, 0, 0, wa.width, wa.height, 8, 0);
51                 if(!image)
52                         throw Exception("Could not create XImage");
53                 image->data=new char[image->bytes_per_line*image->height];
54         }
55 #endif
56 }
57
58 DrawContext::~DrawContext()
59 {
60 #ifndef WIN32
61         if(use_shm)
62         {
63                 XShmDetach(display.get_display(), &shminfo);
64                 shmdt(shminfo.shmaddr);
65                 shmctl(shminfo.shmid, IPC_RMID, 0);
66         }
67
68         XDestroyImage(image);
69 #endif
70 }
71
72 unsigned DrawContext::get_depth() const
73 {
74 #ifdef WIN32
75         return 0;
76 #else
77         return image->bits_per_pixel;
78 #endif
79 }
80
81 unsigned char *DrawContext::get_data()
82 {
83 #ifdef WIN32
84         return 0;
85 #else
86         return reinterpret_cast<unsigned char *>(image->data);
87 #endif
88 }
89
90 void DrawContext::update()
91 {
92 #ifndef WIN32
93         ::Display *dpy=display.get_display();
94
95         GC gc=XCreateGC(dpy, window.get_handle(), 0, 0);
96
97         if(use_shm)
98                 XShmPutImage(dpy, window.get_handle(), gc, image, 0, 0, 0, 0, image->width, image->height, false);
99         else
100                 XPutImage(dpy, window.get_handle(), gc, image, 0, 0, 0, 0, image->width, image->height);
101
102         XFreeGC(dpy, gc);
103 #endif
104 }
105
106 } // namespace Graphics
107 } // namespace Msp