- gtk_window(int width, int height);
- ~gtk_window();
-
- GdkVisual *visual;
- GtkWidget *window;
- GtkWidget *image;
- GtkWidget *panel_hbox;
- GdkImage *img0, *img1;
- GdkPixbuf *pbuf0, *pbuf1;
- unsigned char *bfr, *bfrs, *bfr0, *bfr1;
- unsigned char **rows, **row0, **row1;
- uint64_t flip_bfrs, flip_rows;
- int width, height, linesize;
- int done;
+ Display *display;
+ XShmSegmentInfo shm_info;
+ XImage *ximage;
+ int w, h;
+ unsigned char *data;
+ int shm, sz;
+ uint32_t lsb[3];
+ gg_ximage(Display *display, int w, int h, int shm);
+ ~gg_ximage();
+
+ void put_image(gg_window &gw);
+};
+
+gg_ximage::gg_ximage(Display *display, int w, int h, int shm)
+{
+ this->display = display;
+ this->w = w; this->h = h;
+ this->shm = shm;
+
+ ximage = 0; sz = 0; data = 0;
+ Screen *screen = DefaultScreenOfDisplay(display);
+ Visual *visual = DefaultVisualOfScreen(screen);
+ int depth = DefaultDepthOfScreen(screen);
+
+ if( shm ) {
+ ximage = XShmCreateImage(display, visual, depth, ZPixmap, (char*)NULL, &shm_info, w, h);
+// Create shared memory
+ sz = h * ximage->bytes_per_line;
+ shm_info.shmid = shmget(IPC_PRIVATE, sz + 8, IPC_CREAT | 0777);
+ if(shm_info.shmid < 0) perror("shmget");
+ data = (unsigned char *)shmat(shm_info.shmid, NULL, 0);
+// This causes it to automatically delete when the program exits.
+ shmctl(shm_info.shmid, IPC_RMID, 0);
+ ximage->data = shm_info.shmaddr = (char*)data;
+ shm_info.readOnly = 0;
+// Get the real parameters
+ if(!XShmAttach(display, &shm_info)) perror("XShmAttach");
+ }
+ else {
+ ximage = XCreateImage(display, visual, depth, ZPixmap, 0, (char*)data, w, h, 8, 0);
+ sz = h * ximage->bytes_per_line;
+ data = new unsigned char[sz+8];
+ }
+ memset(data, 0, sz);
+ ximage->data = (char*) data;
+ lsb[0] = ximage->red_mask & ~(ximage->red_mask<<1);
+ lsb[1] = ximage->green_mask & ~(ximage->green_mask<<1);
+ lsb[2] = ximage->blue_mask & ~(ximage->blue_mask<<1);
+}
+
+gg_ximage::~gg_ximage()
+{
+ if( shm ) {
+ data = 0;
+ ximage->data = 0;
+ XDestroyImage(ximage);
+ XShmDetach(display, &shm_info);
+ XFlush(display);
+ shmdt(shm_info.shmaddr);
+ }
+ else {
+ delete [] data;
+ data = 0;
+ ximage->data = 0;
+ XDestroyImage(ximage);
+ }
+}
+
+void gg_ximage::put_image(gg_window &gw)
+{
+ Display *display = gw.display;
+ Window win = gw.win;
+ GC gc = gw.gc;
+ if( shm )
+ XShmPutImage(display, win, gc, ximage, 0,0, 0,0,w,h, 0);
+ else
+ XPutImage(display, win, gc, ximage, 0,0, 0,0,w,h);
+ XFlush(display);
+}