canvas_x11_shm.cpp 1.46 KB
using namespace std;

#include <cstdlib>

#include "canvas_x11_shm.h"

canvas_x11_shm::canvas_x11_shm(unsigned xs, unsigned ys) : 
                canvas_x11(xs, ys) {
    XDestroyImage(ximg);
    //delete [] sinfo->p_screenbuf;

    ximg = XShmCreateImage(disp->getdisplay(), scr->getvisual(),
                           scr->getdepth(), ZPixmap, 0, &shminfo,
                           x_size, y_size);

    shminfo.shmid=shmget(IPC_PRIVATE, ximg->bytes_per_line*ximg->height,
                         IPC_CREAT | 0777);

    if(shminfo.shmid < 0) {
        XDestroyImage(ximg);
        ximg=NULL;
        exit(EXIT_FAILURE);
    }
    else {
        shminfo.shmaddr=ximg->data=(char*)shmat(shminfo.shmid,0,0);
        if(shminfo.shmaddr == (char*)-1) {
            XDestroyImage(ximg);
            ximg=NULL;
            exit(EXIT_FAILURE);
        }
        else {
            shminfo.readOnly=false;
            XShmAttach(disp->getdisplay(), &shminfo);
        }
    }

    sinfo->p_screenbuf=(unsigned char*)(ximg->data);
}

canvas_x11_shm::~canvas_x11_shm() {
    XShmDetach(disp->getdisplay(), &shminfo);
    if(ximg) {
        XDestroyImage(ximg);
        ximg=NULL;
    }
    shmdt(shminfo.shmaddr);
    shmctl(shminfo.shmid, IPC_RMID, NULL);
}

void canvas_x11_shm::blit_screen(void) {
    while(blit != NO_BLIT) {}

    blit=BLIT;
    XShmPutImage(disp->getdisplay(), win->getwindow(), scr->getgc(), 
                 ximg, 0,0,0,0, x_size, y_size, false);
    blit=NO_BLIT;
}