Exemple #1
1
void* icvVideoRender(void* data)
{
    int cameraid = (int)data;
    CvVideoCamera *const camera = &(cameras[cameraid]);
    Display* display;
    int screen_num;
    GC gc;
    char* display_name = NULL;
    Window window = camera->window;
    XWindowAttributes windowattr;
    Visual* visual;
    int windowdepth;
    XImage* image;
    XShmSegmentInfo xshmseg;
    int width  = (camera->renderwidth>0)?camera->renderwidth:camera->videopp.width;
    int height = camera->renderheight?camera->renderheight:camera->videopp.height;
    int picturedepth = camera->videopp.picture.depth;
    int pixelsize;
    XGCValues values;
    IplImage* iplimage;
    time_t start, now;
    int frames = 0;
    float rate = 0;
    Status XShm;
    uchar* imgdata = NULL;
    uchar* tmpbuff = NULL;

    pthread_mutex_lock(&(camera->capturestatemutex));
    if(camera->capturestate != CAPTURING)
    {
        pthread_mutex_unlock(&(camera->capturestatemutex));
        pthread_exit( NULL );
    }
    camera->renderstate=1;
    pthread_cond_signal(&(camera->capturestatecond));
    pthread_mutex_unlock(&(camera->capturestatemutex));
    XInitThreads();

    if ( (display=XOpenDisplay(display_name)) == NULL )

    {
        fprintf( stderr, "cvVideo: cannot connect to X server %s\n",
            XDisplayName(display_name));
        pthread_exit( NULL );
    }

    screen_num = DefaultScreen(display);

    if (XGetWindowAttributes(display, window,
        &windowattr) == 0)
    {
        fprintf(stderr, "icvVideoRender: failed to get window attributes.\n" );
        pthread_exit(NULL);
    }

    if(windowattr.map_state == IsUnmapped)
    {
        fprintf(stderr, "icvVideoRender: window is not mapped \n" );
        pthread_exit(NULL);
    }

    windowdepth = windowattr.depth;
    visual      = windowattr.visual;

    pixelsize = icvVideoWindowPixelsize(windowdepth);

    XShm = XShmQueryExtension(display);
    if(XShm)
    {
        image = XShmCreateImage(display, visual, windowdepth, ZPixmap, NULL,
            &xshmseg, width, height );

        assert(image);

        xshmseg.shmid = shmget (IPC_PRIVATE,
            width*height*pixelsize, IPC_CREAT|0777);

        assert(xshmseg.shmid != -1);
        xshmseg.shmaddr = image->data=(char*)shmat (xshmseg.shmid, 0, 0) ;

        xshmseg.readOnly = False;

        XShmAttach (display, &xshmseg);
    }
    else
    {
        imgdata = (uchar*)malloc(width*height*icvVideoWindowPixelsize(windowdepth)) ;
        image = XCreateImage(display, visual, windowdepth, ZPixmap, 0,
            (char*)imgdata, width,
            height, 8,
            icvVideoWindowPixelsize(windowdepth)
            *width);

        assert(image);
        XInitImage(image);
    }

    gc = XCreateGC(display,window,0, &values );
#ifdef RENDER_FRAMERATE
    start = time(NULL);
#endif

    pthread_mutex_lock(&(camera->capturestatemutex));
    while((camera->capturestate == CAPTURING) && (camera->rendered))
    {
        pthread_mutex_unlock(&(camera->capturestatemutex));
        pthread_mutex_lock(&(camera->updatedmutex));
        while(camera->updated == 0)
            pthread_cond_wait(&(camera->updatedcond), &(camera->updatedmutex));
        camera->updated = 0;
        pthread_mutex_unlock(&(camera->updatedmutex));
        if(cvcamGetProperty(cameraid, "raw_image",&iplimage ))
        {
            assert(image->data);
            if(camera->callback != NULL)
                camera->callback(iplimage);
            if((width==camera->videopp.width)&&
               (height==camera->videopp.height))
            {
                icvvConvert(width, height, width*picturedepth/8, picturedepth,
                            iplimage->imageData, width*pixelsize, pixelsize*8, image->data
                    );
                cvReleaseImage(&iplimage);
            }
            else
            {
                tmpbuff = (uchar*)malloc(camera->videopp.width*camera->videopp.height*
                                         pixelsize) ;
                
                icvvConvert(camera->videopp.width, camera->videopp.height,
                            camera->videopp.width*picturedepth/8, picturedepth,
                            iplimage->imageData, camera->videopp.width*pixelsize,
                            pixelsize*8, (char*)tmpbuff);
                cvReleaseImage(&iplimage);
                
                icvvResizeImage(camera->videopp.width,
                                camera->videopp.height,
                                (camera->videopp.width)*pixelsize, (char*)tmpbuff,
                                width, height,width*pixelsize, image->data, pixelsize*8);
                
                free(tmpbuff);
                
            }
            
            //fprintf(stdout, "cvVideoRendering:image converted!!!!\n");
            
            if(XShm)
            {
                XShmPutImage(display, window, gc,
                             image,0,0,0,0, width,
                             height, False);
            }
            else
            {
                XPutImage(display, window, gc,
                          image,0,0,0,0, width,
                          height);
            }
            
            XSync(display, False);
#ifdef RENDER_FRAMERATE            
            now = time(NULL);
            frames++;
            if (now-start)
                rate = frames/(float)(now-start);
            if((frames%30) == 0)
                fprintf(stdout, "camera %d fps = %f\n", cameraid, rate);
#endif
        }//if(cvcamGetProperty(CAMERA, "raw_image",&image ))

        // stop here if we're paused
        pthread_mutex_lock(&(camera->pausemutex));
        pthread_mutex_unlock(&(camera->pausemutex));
        pthread_mutex_lock(&(camera->capturestatemutex));
    }//while (camera->state == CAPTURING && camera->rendered)
    pthread_mutex_unlock(&(camera->capturestatemutex));

    pthread_mutex_lock(&(camera->capturestatemutex));
#if 0
    if(camera->state != CAPTURING) {
        // we ended because the camera is not capturing anymore
        while (camera->capturestate != FINISHED )
        {
            pthread_cond_wait(&(camera->capturestatecond),&(camera->capturestatemutex));
        }
    }
#endif
    camera->renderstate=0;
    pthread_cond_signal(&(camera->capturestatecond));
    pthread_mutex_unlock(&(camera->capturestatemutex));

    XShmDetach (display, &xshmseg);
    XDestroyImage (image);
    XFreeGC(display,gc);
    shmdt (xshmseg.shmaddr);
    shmctl (xshmseg.shmid, IPC_RMID, 0);
    if(imgdata)
        free(imgdata);  
    pthread_exit(NULL);
}
Exemple #2
0
static int
X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
    X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata;
    SDL_Window *window = renderer->window;
    SDL_VideoDisplay *display = window->display;
    X11_TextureData *data;
    int pitch_alignmask = ((renderdata->scanline_pad / 8) - 1);

    data = (X11_TextureData *) SDL_calloc(1, sizeof(*data));
    if (!data) {
        SDL_OutOfMemory();
        return -1;
    }

    texture->driverdata = data;

    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
        data->yuv =
            SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h);
        if (!data->yuv) {
            return -1;
        }
        data->format = display->current_mode.format;
    } else {
        /* The image/pixmap depth must be the same as the window or you
           get a BadMatch error when trying to putimage or copyarea.
         */
        if (texture->format != display->current_mode.format) {
            SDL_SetError("Texture format doesn't match window format");
            return -1;
        }
        data->format = texture->format;
    }
    data->pitch = texture->w * SDL_BYTESPERPIXEL(data->format);
    data->pitch = (data->pitch + pitch_alignmask) & ~pitch_alignmask;

    if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING) {
#ifndef NO_SHARED_MEMORY
        XShmSegmentInfo *shminfo = &data->shminfo;

        shm_error = True;

        if (SDL_X11_HAVE_SHM) {
            shminfo->shmid =
                shmget(IPC_PRIVATE, texture->h * data->pitch,
                       IPC_CREAT | 0777);
            if (shminfo->shmid >= 0) {
                shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
                shminfo->readOnly = False;
                if (shminfo->shmaddr != (char *) -1) {
                    shm_error = False;
                    X_handler = XSetErrorHandler(shm_errhandler);
                    XShmAttach(renderdata->display, shminfo);
                    XSync(renderdata->display, False);
                    XSetErrorHandler(X_handler);
                    if (shm_error) {
                        shmdt(shminfo->shmaddr);
                    }
                }
                shmctl(shminfo->shmid, IPC_RMID, NULL);
            }
        }
        if (!shm_error) {
            data->pixels = shminfo->shmaddr;

            data->image =
                XShmCreateImage(renderdata->display, renderdata->visual,
                                renderdata->depth, ZPixmap, shminfo->shmaddr,
                                shminfo, texture->w, texture->h);
            if (!data->image) {
                XShmDetach(renderdata->display, shminfo);
                XSync(renderdata->display, False);
                shmdt(shminfo->shmaddr);
                shm_error = True;
            }
        }
        if (shm_error) {
            shminfo->shmaddr = NULL;
        }
        if (!data->image)
#endif /* not NO_SHARED_MEMORY */
        {
            data->pixels = SDL_malloc(texture->h * data->pitch);
            if (!data->pixels) {
                X11_DestroyTexture(renderer, texture);
                SDL_OutOfMemory();
                return -1;
            }

            data->image =
                XCreateImage(renderdata->display, renderdata->visual,
                             renderdata->depth, ZPixmap, 0, data->pixels,
                             texture->w, texture->h,
                             SDL_BYTESPERPIXEL(data->format) * 8,
                             data->pitch);
            if (!data->image) {
                X11_DestroyTexture(renderer, texture);
                SDL_SetError("XCreateImage() failed");
                return -1;
            }
        }
    } else {
        data->pixmap =
            XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w,
                          texture->h, renderdata->depth);
        if (data->pixmap == None) {
            X11_DestroyTexture(renderer, texture);
            SDL_SetError("XCreatePixmap() failed");
            return -1;
        }

        data->image =
            XCreateImage(renderdata->display, renderdata->visual,
                         renderdata->depth, ZPixmap, 0, NULL, texture->w,
                         texture->h, SDL_BYTESPERPIXEL(data->format) * 8,
                         data->pitch);
        if (!data->image) {
            X11_DestroyTexture(renderer, texture);
            SDL_SetError("XCreateImage() failed");
            return -1;
        }
    }

    return 0;
}
Exemple #3
0
/**
 * Initialize the x11 grab device demuxer (public device demuxer API).
 *
 * @param s1 Context from avformat core
 * @param ap Parameters from avformat core
 * @return <ul>
 *          <li>AVERROR(ENOMEM) no memory left</li>
 *          <li>AVERROR(EIO) other failure case</li>
 *          <li>0 success</li>
 *         </ul>
 */
static int
x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
{
    struct x11_grab *x11grab = s1->priv_data;
    Display *dpy;
    AVStream *st = NULL;
    enum PixelFormat input_pixfmt;
    XImage *image;
    int x_off = 0;
    int y_off = 0;
    int use_shm;
    char *param, *offset;
    int ret = 0;
    AVRational framerate;

    param = av_strdup(s1->filename);
    offset = strchr(param, '+');
    if (offset) {
        sscanf(offset, "%d,%d", &x_off, &y_off);
        x11grab->nomouse= strstr(offset, "nomouse");
        *offset= 0;
    }

    if ((ret = av_parse_video_size(&x11grab->width, &x11grab->height, x11grab->video_size)) < 0) {
        av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n");
        goto out;
    }
    if ((ret = av_parse_video_rate(&framerate, x11grab->framerate)) < 0) {
        av_log(s1, AV_LOG_ERROR, "Could not parse framerate: %s.\n", x11grab->framerate);
        goto out;
    }
#if FF_API_FORMAT_PARAMETERS
    if (ap->width > 0)
        x11grab->width = ap->width;
    if (ap->height > 0)
        x11grab->height = ap->height;
    if (ap->time_base.num)
        framerate = (AVRational){ap->time_base.den, ap->time_base.num};
#endif
    av_log(s1, AV_LOG_INFO, "device: %s -> display: %s x: %d y: %d width: %d height: %d\n",
           s1->filename, param, x_off, y_off, x11grab->width, x11grab->height);

    dpy = XOpenDisplay(param);
    if(!dpy) {
        av_log(s1, AV_LOG_ERROR, "Could not open X display.\n");
        ret = AVERROR(EIO);
        goto out;
    }

    st = av_new_stream(s1, 0);
    if (!st) {
        ret = AVERROR(ENOMEM);
        goto out;
    }
    av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */

    use_shm = XShmQueryExtension(dpy);
    av_log(s1, AV_LOG_INFO, "shared memory extension %s found\n", use_shm ? "" : "not");

    if(use_shm) {
        int scr = XDefaultScreen(dpy);
        image = XShmCreateImage(dpy,
                                DefaultVisual(dpy, scr),
                                DefaultDepth(dpy, scr),
                                ZPixmap,
                                NULL,
                                &x11grab->shminfo,
                                x11grab->width, x11grab->height);
        x11grab->shminfo.shmid = shmget(IPC_PRIVATE,
                                        image->bytes_per_line * image->height,
                                        IPC_CREAT|0777);
        if (x11grab->shminfo.shmid == -1) {
            av_log(s1, AV_LOG_ERROR, "Fatal: Can't get shared memory!\n");
            ret = AVERROR(ENOMEM);
            goto out;
        }
        x11grab->shminfo.shmaddr = image->data = shmat(x11grab->shminfo.shmid, 0, 0);
        x11grab->shminfo.readOnly = False;

        if (!XShmAttach(dpy, &x11grab->shminfo)) {
            av_log(s1, AV_LOG_ERROR, "Fatal: Failed to attach shared memory!\n");
            /* needs some better error subroutine :) */
            ret = AVERROR(EIO);
            goto out;
        }
    } else {
        image = XGetImage(dpy, RootWindow(dpy, DefaultScreen(dpy)),
                          x_off,y_off,
                          x11grab->width, x11grab->height,
                          AllPlanes, ZPixmap);
    }

    switch (image->bits_per_pixel) {
    case 8:
        av_log (s1, AV_LOG_DEBUG, "8 bit palette\n");
        input_pixfmt = PIX_FMT_PAL8;
        break;
    case 16:
        if (       image->red_mask   == 0xf800 &&
                   image->green_mask == 0x07e0 &&
                   image->blue_mask  == 0x001f ) {
            av_log (s1, AV_LOG_DEBUG, "16 bit RGB565\n");
            input_pixfmt = PIX_FMT_RGB565;
        } else if (image->red_mask   == 0x7c00 &&
                   image->green_mask == 0x03e0 &&
                   image->blue_mask  == 0x001f ) {
            av_log(s1, AV_LOG_DEBUG, "16 bit RGB555\n");
            input_pixfmt = PIX_FMT_RGB555;
        } else {
            av_log(s1, AV_LOG_ERROR, "RGB ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel);
            av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask);
            ret = AVERROR(EIO);
            goto out;
        }
        break;
    case 24:
        if (        image->red_mask   == 0xff0000 &&
                    image->green_mask == 0x00ff00 &&
                    image->blue_mask  == 0x0000ff ) {
            input_pixfmt = PIX_FMT_BGR24;
        } else if ( image->red_mask   == 0x0000ff &&
                    image->green_mask == 0x00ff00 &&
                    image->blue_mask  == 0xff0000 ) {
            input_pixfmt = PIX_FMT_RGB24;
        } else {
            av_log(s1, AV_LOG_ERROR,"rgb ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel);
            av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask);
            ret = AVERROR(EIO);
            goto out;
        }
        break;
    case 32:
#if 0
        GetColorInfo (image, &c_info);
        if ( c_info.alpha_mask == 0xff000000 && image->green_mask == 0x0000ff00) {
            /* byte order is relevant here, not endianness
             * endianness is handled by avcodec, but atm no such thing
             * as having ABGR, instead of ARGB in a word. Since we
             * need this for Solaris/SPARC, but need to do the conversion
             * for every frame we do it outside of this loop, cf. below
             * this matches both ARGB32 and ABGR32 */
            input_pixfmt = PIX_FMT_ARGB32;
        }  else {
            av_log(s1, AV_LOG_ERROR,"image depth %i not supported ... aborting\n", image->bits_per_pixel);
            return AVERROR(EIO);
        }
#endif
        input_pixfmt = PIX_FMT_RGB32;
        break;
    default:
        av_log(s1, AV_LOG_ERROR, "image depth %i not supported ... aborting\n", image->bits_per_pixel);
        ret = AVERROR(EINVAL);
        goto out;
    }

    x11grab->frame_size = x11grab->width * x11grab->height * image->bits_per_pixel/8;
    x11grab->dpy = dpy;
    x11grab->time_base  = (AVRational){framerate.den, framerate.num};
    x11grab->time_frame = av_gettime() / av_q2d(x11grab->time_base);
    x11grab->x_off = x_off;
    x11grab->y_off = y_off;
    x11grab->image = image;
    x11grab->use_shm = use_shm;

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id = CODEC_ID_RAWVIDEO;
    st->codec->width  = x11grab->width;
    st->codec->height = x11grab->height;
    st->codec->pix_fmt = input_pixfmt;
    st->codec->time_base = x11grab->time_base;
    st->codec->bit_rate = x11grab->frame_size * 1/av_q2d(x11grab->time_base) * 8;

out:
    return ret;
}
Exemple #4
0
static int x11_reset(struct vidisp_st *st, const struct vidsz *sz)
{
	XWindowAttributes attrs;
	XGCValues gcv;
	size_t bufsz, pixsz;
	int err = 0;

	if (!XGetWindowAttributes(st->disp, st->win, &attrs)) {
		warning("x11: cant't get window attributes\n");
		return EINVAL;
	}

	switch (attrs.depth) {

	case 24:
		st->pixfmt = VID_FMT_RGB32;
		pixsz = 4;
		break;

	case 16:
		st->pixfmt = VID_FMT_RGB565;
		pixsz = 2;
		break;

	case 15:
		st->pixfmt = VID_FMT_RGB555;
		pixsz = 2;
		break;

	default:
		warning("x11: colordepth not supported: %d\n", attrs.depth);
		return ENOSYS;
	}

	bufsz = sz->w * sz->h * pixsz;

	if (st->image) {
		XDestroyImage(st->image);
		st->image = NULL;
	}

	if (st->xshmat)
		XShmDetach(st->disp, &st->shm);

	if (st->shm.shmaddr != (char *)-1)
		shmdt(st->shm.shmaddr);

	if (st->shm.shmid >= 0)
		shmctl(st->shm.shmid, IPC_RMID, NULL);

	st->shm.shmid = shmget(IPC_PRIVATE, bufsz, IPC_CREAT | 0777);
	if (st->shm.shmid < 0) {
		warning("x11: failed to allocate shared memory\n");
		return ENOMEM;
	}

	st->shm.shmaddr = shmat(st->shm.shmid, NULL, 0);
	if (st->shm.shmaddr == (char *)-1) {
		warning("x11: failed to attach to shared memory\n");
		return ENOMEM;
	}

	st->shm.readOnly = true;

	x11.shm_error = 0;
	x11.errorh = XSetErrorHandler(error_handler);

	if (!XShmAttach(st->disp, &st->shm)) {
		warning("x11: failed to attach X to shared memory\n");
		return ENOMEM;
	}

	XSync(st->disp, False);
	XSetErrorHandler(x11.errorh);

	if (x11.shm_error)
		info("x11: shared memory disabled\n");
	else
		st->xshmat = true;

	gcv.graphics_exposures = false;

	st->gc = XCreateGC(st->disp, st->win, GCGraphicsExposures, &gcv);
	if (!st->gc) {
		warning("x11: failed to create graphics context\n");
		return ENOMEM;
	}

	if (st->xshmat) {
		st->image = XShmCreateImage(st->disp, attrs.visual,
					    attrs.depth, ZPixmap,
					    st->shm.shmaddr, &st->shm,
					    sz->w, sz->h);
	}
	else {
		st->image = XCreateImage(st->disp, attrs.visual,
					 attrs.depth, ZPixmap, 0,
					 st->shm.shmaddr,
					 sz->w, sz->h, 32, 0);

	}
	if (!st->image) {
		warning("x11: Failed to create X image\n");
		return ENOMEM;
	}

	XResizeWindow(st->disp, st->win, sz->w, sz->h);

	st->size = *sz;

	return err;
}
Exemple #5
0
void	*mlx_int_new_xshm_image(t_xvar *xvar,int width,int height,int format)
{
  t_img	*img;
  int	(*save_handler)();

  if (!(img = malloc(sizeof(*img))))
    return ((void *)0);
  bzero(img,sizeof(*img));
  img->data = 0;
  img->image = XShmCreateImage(xvar->display,xvar->visual,xvar->depth,
			       format,img->data,&(img->shm),width,height);
  if (!img->image)
    {
      free(img);
      return ((void *)0);
    }
  img->width = width;
  img->height = height;
  img->size_line = img->image->bytes_per_line;
  img->bpp = img->image->bits_per_pixel;
  img->format = format;
  img->shm.shmid = shmget(IPC_PRIVATE,(width+32)*height*4,IPC_CREAT|0777);
  if (img->shm.shmid==-1)
    {
      XDestroyImage(img->image);
      free(img);
      return ((void *)0);
    }
  img->data = img->shm.shmaddr = img->image->data = shmat(img->shm.shmid,0,0);
  if (img->data==(void *)-1)
    {
      shmctl(img->shm.shmid,IPC_RMID,0);
      XDestroyImage(img->image);
      free(img);
      return ((void *)0);
    }
  img->shm.readOnly = False;
  mlx_X_error = 0;
  save_handler = XSetErrorHandler(shm_att_pb);
  if (!XShmAttach(xvar->display,&(img->shm)) ||
      0&XSync(xvar->display,False) || mlx_X_error)
    {
      XSetErrorHandler(save_handler);
      shmdt(img->data);
      shmctl(img->shm.shmid,IPC_RMID,0);
      XDestroyImage(img->image);
      free(img);
      return ((void *)0);
    }
  XSetErrorHandler(save_handler);
  shmctl(img->shm.shmid,IPC_RMID,0);
  if (xvar->pshm_format==format)
    {
      img->pix = XShmCreatePixmap(xvar->display,xvar->root,img->shm.shmaddr,
				  &(img->shm),width,height,xvar->depth);
      img->type = MLX_TYPE_SHM_PIXMAP;
    }
  else
    {
      img->pix = XCreatePixmap(xvar->display,xvar->root,
			       width,height,xvar->depth);
      img->type = MLX_TYPE_SHM;
    }
  if (xvar->do_flush)
    XFlush(xvar->display);
  return (img);
}
Exemple #6
0
RXImage*
RCreateXImage(RContext *context, int depth, unsigned width, unsigned height)
{
    RXImage *rximg;
    Visual *visual = context->visual;

    rximg = malloc(sizeof(RXImage));
    if (!rximg) {
        RErrorCode = RERR_NOMEMORY;
        return NULL;
    }

#ifndef XSHM
    rximg->image = XCreateImage(context->dpy, visual, depth,
                                ZPixmap, 0, NULL, width, height, 8, 0);
    if (!rximg->image) {
        free(rximg);
        RErrorCode = RERR_XERROR;
        return NULL;
    }
    rximg->image->data = malloc(rximg->image->bytes_per_line*height);
    if (!rximg->image->data) {
        XDestroyImage(rximg->image);
        free(rximg);
        RErrorCode = RERR_NOMEMORY;
        return NULL;
    }

#else /* XSHM */
    if (!context->attribs->use_shared_memory) {
    retry_without_shm:

        context->attribs->use_shared_memory = 0;
        rximg->is_shared = 0;
        rximg->image = XCreateImage(context->dpy, visual, depth,
                                    ZPixmap, 0, NULL, width, height, 8, 0);
        if (!rximg->image) {
            free(rximg);
            RErrorCode = RERR_XERROR;
            return NULL;
        }
        rximg->image->data = malloc(rximg->image->bytes_per_line*height);
        if (!rximg->image->data) {
            XDestroyImage(rximg->image);
            free(rximg);
            RErrorCode = RERR_NOMEMORY;
            return NULL;
        }
    } else {
        rximg->is_shared = 1;

        rximg->info.readOnly = False;

        rximg->image = XShmCreateImage(context->dpy, visual, depth,
                                       ZPixmap, NULL, &rximg->info, width,
                                       height);

        rximg->info.shmid = shmget(IPC_PRIVATE,
                                   rximg->image->bytes_per_line*height,
                                   IPC_CREAT|0777);
        if (rximg->info.shmid < 0) {
            context->attribs->use_shared_memory = 0;
            perror("wrlib: could not allocate shared memory segment");
            XDestroyImage(rximg->image);
            goto retry_without_shm;
        }

        rximg->info.shmaddr = shmat(rximg->info.shmid, 0, 0);
        if (rximg->info.shmaddr == (void*)-1) {
            context->attribs->use_shared_memory = 0;
            if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
                perror("wrlib: shmctl");
            perror("wrlib: could not allocate shared memory");
            XDestroyImage(rximg->image);
            goto retry_without_shm;
        }

        shmError = 0;
        XSync(context->dpy, False);
        oldErrorHandler = XSetErrorHandler(errorHandler);
        XShmAttach(context->dpy, &rximg->info);
        XSync(context->dpy, False);
        XSetErrorHandler(oldErrorHandler);

        rximg->image->data = rximg->info.shmaddr;
        /*	rximg->image->obdata = &(rximg->info);*/

        if (shmError) {
            context->attribs->use_shared_memory = 0;
            XDestroyImage(rximg->image);
            if (shmdt(rximg->info.shmaddr) < 0)
                perror("wrlib: shmdt");
            if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
                perror("wrlib: shmctl");
            /*	    printf("wrlib:error attaching shared memory segment to XImage\n");
             */
            goto retry_without_shm;
        }
    }
#endif /* XSHM */

    return rximg;
}
Exemple #7
0
static int
makesharedfb(void)
{
	XShmSegmentInfo *shminfo;

	shminfo = malloc(sizeof(XShmSegmentInfo));
	if(shminfo == nil) {
		fprint(2, "emu: cannot allocate XShmSegmentInfo\n");
		cleanexit(0);
	}

	/* setup to catch X11 error(s) */
	XSync(xdisplay, 0); 
	shm_got_x_error = 0; 
	if(old_handler != shm_ehandler)
		old_handler = XSetErrorHandler(shm_ehandler);
	if(old_io_handler != shm_ehandler)
		old_io_handler = XSetErrorHandler(shm_ehandler);

	img = XShmCreateImage(xdisplay, xvis, xscreendepth, ZPixmap, 
			      NULL, shminfo, Xsize, Ysize);
	XSync(xdisplay, 0);

	/* did we get an X11 error? if so then try without shm */
	if(shm_got_x_error) {
		free(shminfo);
		shminfo = NULL;
		clean_errhandlers();
		return 0;
	}
	
	if(img == nil) {
		fprint(2, "emu: cannot allocate virtual screen buffer\n");
		cleanexit(0);
	}
	
	shminfo->shmid = shmget(IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777);
	shminfo->shmaddr = img->data = shmat(shminfo->shmid, 0, 0);
	shminfo->readOnly = True;

	if(!XShmAttach(xdisplay, shminfo)) {
		fprint(2, "emu: cannot allocate virtual screen buffer\n");
		cleanexit(0);
	}
	XSync(xdisplay, 0);

	/*
	 * Delete the shared segment right now; the segment
	 * won't actually go away until both the client and
	 * server have deleted it.  The server will delete it
	 * as soon as the client disconnects, so we might as
	 * well delete our side now as later.
	 */
	shmctl(shminfo->shmid, IPC_RMID, 0);

	/* did we get an X11 error? if so then try without shm */
	if(shm_got_x_error) {
		XDestroyImage(img);
		XSync(xdisplay, 0);
		free(shminfo);
		shminfo = NULL;
		clean_errhandlers();
		return 0;
	}

	gscreendata = malloc(Xsize * Ysize * (displaydepth >> 3));
	if(gscreendata == nil) {
		fprint(2, "emu: cannot allocate screen buffer (%dx%dx%d)\n", Xsize, Ysize, displaydepth);
		cleanexit(0);
	}
	xscreendata = (uchar*)img->data;
	
	clean_errhandlers();
	return 1;
}
static void
_cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap)
{
  CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
  Display *display;
  Visual *visual;
  CoglPixelFormat image_format;
  XImage *image;
  int src_x, src_y;
  int x, y, width, height;
  int bpp;
  int offset;
  CoglError *ignore = NULL;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  display = cogl_xlib_renderer_get_display (ctx->display->renderer);
  visual = tex_pixmap->visual;

  /* If the damage region is empty then there's nothing to do */
  if (tex_pixmap->damage_rect.x2 == tex_pixmap->damage_rect.x1)
    return;

  x = tex_pixmap->damage_rect.x1;
  y = tex_pixmap->damage_rect.y1;
  width = tex_pixmap->damage_rect.x2 - x;
  height = tex_pixmap->damage_rect.y2 - y;

  /* We lazily create the texture the first time it is needed in case
     this texture can be entirely handled using the GLX texture
     instead */
  if (tex_pixmap->tex == NULL)
    {
      CoglPixelFormat texture_format;

      texture_format = (tex_pixmap->depth >= 32
                        ? COGL_PIXEL_FORMAT_RGBA_8888_PRE
                        : COGL_PIXEL_FORMAT_RGB_888);

      tex_pixmap->tex = create_fallback_texture (ctx,
                                                 tex->width,
                                                 tex->height,
                                                 texture_format);
    }

  if (tex_pixmap->image == NULL)
    {
      /* If we also haven't got a shm segment then this must be the
         first time we've tried to update, so lets try allocating shm
         first */
      if (tex_pixmap->shm_info.shmid == -1)
        try_alloc_shm (tex_pixmap);

      if (tex_pixmap->shm_info.shmid == -1)
        {
          COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetImage", tex_pixmap);

          /* We'll fallback to using a regular XImage. We'll download
             the entire area instead of a sub region because presumably
             if this is the first update then the entire pixmap is
             needed anyway and it saves trying to manually allocate an
             XImage at the right size */
          tex_pixmap->image = XGetImage (display,
                                         tex_pixmap->pixmap,
                                         0, 0,
                                         tex->width, tex->height,
                                         AllPlanes, ZPixmap);
          image = tex_pixmap->image;
          src_x = x;
          src_y = y;
        }
      else
        {
          COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XShmGetImage",
                     tex_pixmap);

          /* Create a temporary image using the beginning of the
             shared memory segment and the right size for the region
             we want to update. We need to reallocate the XImage every
             time because there is no XShmGetSubImage. */
          image = XShmCreateImage (display,
                                   tex_pixmap->visual,
                                   tex_pixmap->depth,
                                   ZPixmap,
                                   NULL,
                                   &tex_pixmap->shm_info,
                                   width,
                                   height);
          image->data = tex_pixmap->shm_info.shmaddr;
          src_x = 0;
          src_y = 0;

          XShmGetImage (display, tex_pixmap->pixmap, image, x, y, AllPlanes);
        }
    }
  else
    {
      COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetSubImage", tex_pixmap);

      image = tex_pixmap->image;
      src_x = x;
      src_y = y;

      XGetSubImage (display,
                    tex_pixmap->pixmap,
                    x, y, width, height,
                    AllPlanes, ZPixmap,
                    image,
                    x, y);
    }

  image_format =
    _cogl_util_pixel_format_from_masks (visual->red_mask,
                                        visual->green_mask,
                                        visual->blue_mask,
                                        image->depth,
                                        image->bits_per_pixel,
                                        image->byte_order == LSBFirst);

  bpp = _cogl_pixel_format_get_bytes_per_pixel (image_format);
  offset = image->bytes_per_line * src_y + bpp * src_x;

  _cogl_texture_set_region (tex_pixmap->tex,
                            width,
                            height,
                            image_format,
                            image->bytes_per_line,
                            ((const uint8_t *) image->data) + offset,
                            x, y,
                            0, /* level */
                            &ignore);

  /* If we have a shared memory segment then the XImage would be a
     temporary one with no data allocated so we can just XFree it */
  if (tex_pixmap->shm_info.shmid != -1)
    XFree (image);

  memset (&tex_pixmap->damage_rect, 0, sizeof (CoglDamageRectangle));
}
Exemple #9
0
bool video::init_window(int xsize, int ysize)
{
    { //enclose local variables before fail label
    g_sizex = xsize; g_sizey = ysize;

    // Open the display
    if (!dpy) {
        dpy = XOpenDisplay(display_name);
        if (!dpy) {
            fprintf(stderr, "Can't open X11 display %s\n", XDisplayName(display_name));
            goto fail;
        }
    }
    int theScreen = DefaultScreen(dpy);
    scrn = ScreenOfDisplay(dpy, theScreen);
    dispdepth = DefaultDepth(dpy, theScreen);
    XVisualInfo vinfo;
    if (!( (dispdepth >= 15 && dispdepth <= 32 && XMatchVisualInfo(dpy, theScreen, dispdepth, TrueColor, &vinfo) )
        || XMatchVisualInfo(dpy, theScreen, 24, TrueColor, &vinfo)
        || XMatchVisualInfo(dpy, theScreen, 32, TrueColor, &vinfo)
        || XMatchVisualInfo(dpy, theScreen, 16, TrueColor, &vinfo)
        || XMatchVisualInfo(dpy, theScreen, 15, TrueColor, &vinfo)
        )) {
        fprintf(stderr, "Display has no appropriate True Color visual\n");
        goto fail;
    }
    vis = vinfo.visual;
    depth = dispdepth = vinfo.depth;
    mask2bits(vinfo.red_mask, red_mask, red_shift);
    mask2bits(vinfo.green_mask, green_mask, green_shift);
    mask2bits(vinfo.blue_mask, blue_mask, blue_shift);
    rootW = RootWindow(dpy, theScreen);
    cmap = XCreateColormap(dpy, rootW, vis, AllocNone);
    XSetWindowAttributes attrs;
    attrs.backing_store = Always;
    attrs.colormap = cmap;
    attrs.event_mask = StructureNotifyMask|KeyPressMask|ButtonPressMask|ButtonReleaseMask;
    attrs.background_pixel = BlackPixelOfScreen(scrn);
    attrs.border_pixel = WhitePixelOfScreen(scrn);
    win = XCreateWindow(dpy, rootW,
        0, 0, xsize, ysize, 2,
        dispdepth, InputOutput, vis,
        CWBackingStore | CWColormap | CWEventMask |
        CWBackPixel | CWBorderPixel,
        &attrs);
    if(!win) {
        fprintf(stderr, "Can't create the window\n");
        goto fail;
    }
    XSizeHints sh;
    sh.flags = PSize | PMinSize | PMaxSize;
    sh.width = sh.min_width = sh.max_width = xsize;
    sh.height = sh.min_height = sh.max_height = ysize;
    XSetStandardProperties( dpy, win, g_video->title, g_video->title, None, NULL, 0, &sh );
    _XA_WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", false);
    XSetWMProtocols(dpy, win, &_XA_WM_DELETE_WINDOW, 1);
    gc = XCreateGC(dpy, win, 0L, &xgcv);
    XMapRaised(dpy, win);
    XFlush(dpy);
#ifdef X_FULLSYNC
	XSynchronize(dpy, true);
#endif
    XSetErrorHandler(xerr_handler);

    int imgbytes = xsize*ysize*(dispdepth<=16?2:4);
    const char *vidstr;
#ifndef X_NOSHMEM
    int major, minor, pixmaps;
    if(XShmQueryExtension(dpy) &&
       XShmQueryVersion(dpy, &major, &minor, &pixmaps))
    { // Shared memory
        if(NULL!=getenv(NOSHMEM_env_var_name) && 0!=strcmp("0",getenv(NOSHMEM_env_var_name))) {
            goto generic;
        }
        shmseginfo.shmid = shmget(IPC_PRIVATE, imgbytes, IPC_CREAT|0777);
        if(shmseginfo.shmid < 0) {
            fprintf(stderr, "Warning: Can't get shared memory: %s\n", strerror(errno));
            goto generic;
        }
        g_pImg = (unsigned int*)(shmseginfo.shmaddr = (char*)shmat(shmseginfo.shmid, 0, 0));
        if(g_pImg == (unsigned int*)-1) {
            fprintf(stderr, "Warning: Can't attach to shared memory: %s\n", strerror(errno));
            shmctl(shmseginfo.shmid, IPC_RMID, NULL);
            goto generic;
        }
        shmseginfo.readOnly = false;
        if(!XShmAttach(dpy, &shmseginfo) || x_error) {
            char err[256]; XGetErrorText(dpy, x_error, err, 255);
            fprintf(stderr, "Warning: Can't attach shared memory to display: %s (%d)\n", err, x_error);
            shmdt(shmseginfo.shmaddr); shmctl(shmseginfo.shmid, IPC_RMID, NULL);
            goto generic;
        }
        already_called_X_ShmAttach = true;

#ifndef X_NOSHMPIX
        if(pixmaps && XShmPixmapFormat(dpy) == ZPixmap)
        { // Pixmaps
            vidtype = 2; vidstr = "X11 shared memory pixmap";
            pixmap = XShmCreatePixmap(dpy, win, (char*)g_pImg, &shmseginfo, xsize, ysize, dispdepth);
            XSetWindowBackgroundPixmap(dpy, win, pixmap);
        } else
#endif//!X_NOSHMPIX
        { // Standard
            vidtype = 1; vidstr = "X11 shared memory";
            ximage = XShmCreateImage(dpy, vis, dispdepth,
                ZPixmap, 0, &shmseginfo, xsize, ysize);
            if(!ximage) {
                fprintf(stderr, "Can't create the shared image\n");
                goto fail;
            }
            assert(ximage->bytes_per_line == xsize*(dispdepth<=16?2:4));
            ximage->data = shmseginfo.shmaddr;
        }
    } else
#endif
    {
#ifndef X_NOSHMEM
generic:
#endif
        vidtype = 0; vidstr = "generic X11";
        g_pImg = new unsigned int[imgbytes/sizeof(int)];
        ximage = XCreateImage(dpy, vis, dispdepth, ZPixmap, 0, (char*)g_pImg, xsize, ysize, 32, imgbytes/ysize);
        if(!ximage) {
            fprintf(stderr, "Can't create the image\n");
            goto fail;
        }
    }
    // Note: It may be more efficient to adopt the server's byte order
    //       and swap once per get_color() call instead of once per pixel.
    const uint32_t probe = 0x03020100;
    const bool big_endian = (((const char*)(&probe))[0]==0x03);
    ximage->byte_order = big_endian ? MSBFirst : LSBFirst;

    printf("Note: using %s with %s visual for %d-bit color depth\n", vidstr, vis==DefaultVisual(dpy, theScreen)?"default":"non-default", dispdepth);
    running = true;
    return true;
    } // end of enclosing local variables
fail:
    terminate(); init_console();
    return false;
}
Exemple #10
0
int x11_shadow_xshm_init(x11ShadowSubsystem* subsystem)
{
	Bool pixmaps;
	int major, minor;
	XGCValues values;

	if (!XShmQueryExtension(subsystem->display))
		return -1;

	if (!XShmQueryVersion(subsystem->display, &major, &minor, &pixmaps))
		return -1;

	if (!pixmaps)
		return -1;

	subsystem->fb_shm_info.shmid = -1;
	subsystem->fb_shm_info.shmaddr = (char*) -1;
	subsystem->fb_shm_info.readOnly = False;

	subsystem->fb_image = XShmCreateImage(subsystem->display, subsystem->visual, subsystem->depth,
			ZPixmap, NULL, &(subsystem->fb_shm_info), subsystem->width, subsystem->height);

	if (!subsystem->fb_image)
	{
		WLog_ERR(TAG, "XShmCreateImage failed");
		return -1;
	}

	subsystem->fb_shm_info.shmid = shmget(IPC_PRIVATE,
			subsystem->fb_image->bytes_per_line * subsystem->fb_image->height, IPC_CREAT | 0600);

	if (subsystem->fb_shm_info.shmid == -1)
	{
		WLog_ERR(TAG, "shmget failed");
		return -1;
	}

	subsystem->fb_shm_info.shmaddr = shmat(subsystem->fb_shm_info.shmid, 0, 0);
	subsystem->fb_image->data = subsystem->fb_shm_info.shmaddr;

	if (subsystem->fb_shm_info.shmaddr == ((char*) -1))
	{
		WLog_ERR(TAG, "shmat failed");
		return -1;
	}

	if (!XShmAttach(subsystem->display, &(subsystem->fb_shm_info)))
		return -1;

	XSync(subsystem->display, False);

	shmctl(subsystem->fb_shm_info.shmid, IPC_RMID, 0);

	subsystem->fb_pixmap = XShmCreatePixmap(subsystem->display,
			subsystem->root_window, subsystem->fb_image->data, &(subsystem->fb_shm_info),
			subsystem->fb_image->width, subsystem->fb_image->height, subsystem->fb_image->depth);

	XSync(subsystem->display, False);

	if (!subsystem->fb_pixmap)
		return -1;

	values.subwindow_mode = IncludeInferiors;
	values.graphics_exposures = False;

	subsystem->xshm_gc = XCreateGC(subsystem->display, subsystem->root_window,
			GCSubwindowMode | GCGraphicsExposures, &values);

	XSetFunction(subsystem->display, subsystem->xshm_gc, GXcopy);
	XSync(subsystem->display, False);

	return 1;
}
/* Tries to allocate enough shared mem to handle a full size
 * update size of the X Pixmap. */
static void
try_alloc_shm (CoglTexturePixmapX11 *tex_pixmap)
{
  CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
  XImage *dummy_image;
  Display *display;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  display = cogl_xlib_renderer_get_display (ctx->display->renderer);

  if (!XShmQueryExtension (display))
    return;

  /* We are creating a dummy_image so we can have Xlib calculate
   * image->bytes_per_line - including any magic padding it may
   * want - for the largest possible ximage we might need to use
   * when handling updates to the texture.
   *
   * Note: we pass a NULL shminfo here, but that has no bearing
   * on the setup of the XImage, except that ximage->obdata will
   * == NULL.
   */
  dummy_image =
    XShmCreateImage (display,
                     tex_pixmap->visual,
                     tex_pixmap->depth,
                     ZPixmap,
                     NULL,
                     NULL, /* shminfo, */
                     tex->width,
                     tex->height);
  if (!dummy_image)
    goto failed_image_create;

  tex_pixmap->shm_info.shmid = shmget (IPC_PRIVATE,
                                       dummy_image->bytes_per_line
                                       * dummy_image->height,
                                       IPC_CREAT | 0777);
  if (tex_pixmap->shm_info.shmid == -1)
    goto failed_shmget;

  tex_pixmap->shm_info.shmaddr = shmat (tex_pixmap->shm_info.shmid, 0, 0);
  if (tex_pixmap->shm_info.shmaddr == (void *) -1)
    goto failed_shmat;

  tex_pixmap->shm_info.readOnly = False;

  if (XShmAttach (display, &tex_pixmap->shm_info) == 0)
    goto failed_xshmattach;

  XDestroyImage (dummy_image);

  return;

 failed_xshmattach:
  g_warning ("XShmAttach failed");
  shmdt (tex_pixmap->shm_info.shmaddr);

 failed_shmat:
  g_warning ("shmat failed");
  shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0);

 failed_shmget:
  g_warning ("shmget failed");
  XDestroyImage (dummy_image);

 failed_image_create:
  tex_pixmap->shm_info.shmid = -1;
}
Exemple #12
0
QNativeImage::QNativeImage(int width, int height, QImage::Format format,bool /* isTextBuffer */, QWidget *widget)
    : xshmimg(0), xshmpm(0)
{
    QX11Info info = widget->x11Info();

    int dd = info.depth();
    Visual *vis = (Visual*) info.visual();

    if (!X11->use_mitshm || format != QImage::Format_RGB16 && X11->bppForDepth.value(dd) != 32) {
        image = QImage(width, height, format);
        // follow good coding practice and set xshminfo attributes, though values not used in this case
        xshminfo.readOnly = true;
        xshminfo.shmaddr = 0;
        xshminfo.shmid = 0;
        xshminfo.shmseg = 0;
        return;
    }

    xshmimg = XShmCreateImage(X11->display, vis, dd, ZPixmap, 0, &xshminfo, width, height);
    if (!xshmimg) {
        qWarning("QNativeImage: Unable to create shared XImage.");
        return;
    }

    bool ok;
    xshminfo.shmid = shmget(IPC_PRIVATE, xshmimg->bytes_per_line * xshmimg->height,
                            IPC_CREAT | 0700);
    ok = xshminfo.shmid != -1;
    if (ok) {
        xshmimg->data = (char*)shmat(xshminfo.shmid, 0, 0);
        xshminfo.shmaddr = xshmimg->data;
        ok = (xshminfo.shmaddr != (char*)-1);
        if (ok)
            image = QImage((uchar *)xshmimg->data, width, height, format);
    }
    xshminfo.readOnly = false;
    if (ok) {
        ok = XShmAttach(X11->display, &xshminfo);
        XSync(X11->display, False);
        if (shmctl(xshminfo.shmid, IPC_RMID, 0) == -1)
            qWarning() << "Error while marking the shared memory segment to be destroyed";
    }
    if (!ok) {
        qWarning() << "QNativeImage: Unable to attach to shared memory segment.";
        if (xshmimg->data) {
            free(xshmimg->data);
            xshmimg->data = 0;
        }
        XDestroyImage(xshmimg);
        xshmimg = 0;
        if (xshminfo.shmaddr)
            shmdt(xshminfo.shmaddr);
        if (xshminfo.shmid != -1)
            shmctl(xshminfo.shmid, IPC_RMID, 0);
        return;
    }
    if (X11->use_mitshm_pixmaps) {
        xshmpm = XShmCreatePixmap(X11->display, DefaultRootWindow(X11->display), xshmimg->data,
                                  &xshminfo, width, height, dd);
        if (!xshmpm) {
            qWarning() << "QNativeImage: Unable to create shared Pixmap.";
        }
    }
}
Exemple #13
0
  int main (void)
  {
    int i;
  
    int allocateOK;
  
    ximg = NULL;
  
  	
    d = XOpenDisplay (NULL);
  
    if (!d)
      fputs ("Couldn't open display\n", stderr), exit (1);
  
    screen = DefaultScreen (d);
    gc = DefaultGC (d, screen);
  
    /* Find a visual */
  
    vis.screen = screen;
    vlist = XGetVisualInfo (d, VisualScreenMask, &vis, &match);
  
    if (!vlist)
      fputs ("No matched visuals\n", stderr), exit (1);
  
    vis = vlist[0];
    XFree (vlist);
		
  	// That's not a fair comparison colormap_size is depth in bits!
    // if (vis.colormap_size < COLORS)
      // printf("Colormap is too small: %i.\n",vis.colormap_size); // , exit (1);
		printf("Colour depth: %i\n",vis.colormap_size);
  
    win = XCreateSimpleWindow (d, DefaultRootWindow (d),
			       0, 0, WIN_W, WIN_H, 0,
			       WhitePixel (d, screen), BlackPixel (d, screen));
  
	  int xclass=get_xvisinfo_class(vis);
		// printf("class = %i\n",xclass);
	  stylee = ( vis.depth > 8 ? styleeTrueColor : styleePrivate );
	  // printf("stylee=%i\n",stylee);
  
    if ( get_xvisinfo_class(vis) % 2 == 1) {	/* The odd numbers can redefine colors */
  
			  // printf("%i\n",get_xvisinfo_class(vis));
	  	
      colormap = DefaultColormap (d, screen);
		  Visual *defaultVisual=DefaultVisual(d,screen);
	  	
      /* Allocate cells */
      allocateOK = (XAllocColorCells (d, colormap, 1,
							      NULL, 0, color, COLORS) != 0);

			// printf("Allocated OK? %i\n",allocateOK);
			
      if (allocateOK) {
  
			  // printf("Allocated OK\n");
        // This doesn't work for installed colormap!
  
        /* Modify the colorcells */
        for (i = 0; i < COLORS; i++)
				  xrgb[i].pixel = color[i];
  
        XStoreColors (d, colormap, xrgb, COLORS);
  
		  } else {

			  colormap = XCreateColormap(d,win,defaultVisual,AllocNone);
		  	
    	  // redocolors();
					  	
      }
  
		  // black = XBlackPixel(d,screen);
		  // white = XWhitePixel(d,screen);
  
    } else if ( get_xvisinfo_class(vis) == TrueColor) {
      colormap = DefaultColormap (d, screen);
					  // printf("TrueColor %i = %i\n",xclass,TrueColor);
      /* This will lookup the color and sets the xrgb[i].pixel value */
      // for (i = 0; i < COLORS; i++)
        // XAllocColor (d, colormap, &xrgb[i]);
    } else
      fprintf (stderr, "Not content with visual class %d.\n",
	       get_xvisinfo_class(vis) ), exit (1);
  
    /* Find out if MITSHM is supported and useable */
    printf ("MITSHM: ");
  
    if (XShmQueryVersion (d, &mitshm_major_code,
			  &mitshm_minor_code, &shared_pixmaps)) {
      int (*handler) (Display *, XErrorEvent *);
      ximg = XShmCreateImage (d, vis.visual,
			     vis.depth, XShmPixmapFormat (d),
			     NULL, &shminfo, WIN_W, WIN_H);
      shminfo.shmid = shmget (IPC_PRIVATE,
			      ximg->bytes_per_line * ximg->height,
			      IPC_CREAT | 0777);
      shminfo.shmaddr = (char *)shmat (shminfo.shmid, 0, 0);
		  ximg->data = (char *)shminfo.shmaddr;
  
      handler = XSetErrorHandler (mitshm_handler);
      XShmAttach (d, &shminfo);	/* Tell the server to attach */
      XSync (d, 0);
      XSetErrorHandler (handler);
  
      shmctl (shminfo.shmid, IPC_RMID, 0);
      /* Mark this shm segment for deletion at once. The segment will
       * automatically become released when both the server and this
       * client have detached from it.
       * (Process termination automagically detach shm segments) */
  
      if (!can_use_mitshm) {
        shmdt (shminfo.shmaddr);
        ximg = NULL;
      }
    }
  
    if (ximg == NULL) {
      can_use_mitshm = 0;
      /* XInitImage(ximg); */
      ximg = XCreateImage (d, vis.visual, vis.depth, ZPixmap,
			  0, (char *)malloc (WIN_W * WIN_H), WIN_W, WIN_H, 8, 0);
    }
  
    if (can_use_mitshm)
      printf ("YES!\n");
    else
      printf ("NO, using fallback instead.\n");
  
    // DrawFractal (ximg,xrgb);
  
    XSelectInput (d, win, ButtonPressMask | ExposureMask);
    XMapWindow (d, win);
  
  
  
  
    real_main();


  
      // XNextEvent (d, &ev);
      // switch (ev.type) {
      // case ButtonPress:
        // should_quit = 1;
        // break;
      // case Expose:
        // if (can_use_mitshm)
				  // XShmPutImage (d, win, gc, img, 0, 0, 0, 0, WIN_W, WIN_H, True);
        // else
				  // XPutImage (d, win, gc, img, 0, 0, 0, 0, WIN_W, WIN_H);
        // break;
      // default:
			  // break;
      // }
  
  
  
    if (get_xvisinfo_class(vis) % 2 == 1 || get_xvisinfo_class(vis) == TrueColor) {
      unsigned long color[COLORS];
  
      if (allocateOK) {
        for (i = 0; i < COLORS; i++)
				  color[i] = xrgb[i].pixel;
        XFreeColors (d, colormap, color, COLORS, 0);
      }				/* Allocated colors freed */
    } else {
      XUninstallColormap (d, colormap);
    }
  
    if (can_use_mitshm) {
      XShmDetach (d, &shminfo);	/* Server detached */
      XDestroyImage (ximg);	/* Image struct freed */
      shmdt (shminfo.shmaddr);	/* We're detached */
    } else
      XDestroyImage (ximg);	/* Image struct freed */
  
    XDestroyWindow (d, win);	/* Window removed */
    XCloseDisplay (d);		/* Display disconnected */
  
    /* So you can see how your computer compares to your friend's */
    getrusage (RUSAGE_SELF, &resource_utilization);
		float seconds=(float)resource_utilization.ru_utime.tv_sec
						     +(float)resource_utilization.ru_utime.tv_usec*0.000000001;
		printf("CPU seconds per frame: %f\n",seconds/(float)frameno);
    // printf ("CPU seconds consumed: %ds and %dµs\n",
	    // (int) resource_utilization.ru_utime.tv_sec,
	    // (int) resource_utilization.ru_utime.tv_usec);
  
    return 0;
  }
/* This name doesn't really cover this function, since it also sets up mouse
   and keyboard. This is done over here, since on most display targets the
   mouse and keyboard can't be setup before the display has. */
int x11_window_open_display(int reopen)
{
        int needed_width, needed_height;

        /* set aspect_ratio, do this early since this can change yarbsize */
        mode_set_aspect_ratio((double)screen->width/screen->height);

        needed_width  = sysdep_display_params.width * 
          sysdep_display_params.widthscale;
        needed_height = sysdep_display_params.yarbsize?
          sysdep_display_params.yarbsize:
          sysdep_display_params.height * sysdep_display_params.heightscale;

        if(!reopen)
        {
          XGCValues xgcv;
          /* setup the sysdep_display_properties struct */
          sysdep_display_properties.max_width  = -1;
          sysdep_display_properties.max_height = -1;
          if (x11_init_palette_info())
                  return 1;

          /* create a window */
          if (x11_create_window(&window_width, &window_height, X11_FIXED))
            return 1;

          if ((needed_width > window_width) || (needed_height > window_height))
          {
            fprintf (stderr, "OSD ERROR: Window is to small: %dx%d, needed %dx%d\n",
              needed_width, needed_height, window_width, window_height);
            return 1;
          }

          startx = ((window_width  - needed_width)  / 2) & ~3;
          starty = ((window_height - window_height) / 2) & ~3;

          /* create gc */
          gc = XCreateGC (display, window, 0, &xgcv);

	  /* open xinput */
          xinput_open(0, ExposureMask);
        }
        else
        {
          sysdep_display_effect_close();
          
          if ( (needed_width  > image->width)  ||
               (needed_height > image->height) )
            x11_window_destroy_image();
          
          x11_resize_window(&window_width, &window_height, X11_FIXED);
        }

        /* create and setup the image */
        if (!image)
        {
          char *scaled_buffer_ptr;
          int image_width  = sysdep_display_params.widthscale *
            sysdep_display_params.max_width;
          int image_height = sysdep_display_params.yarbsize?
            sysdep_display_params.yarbsize:
            sysdep_display_params.max_height * sysdep_display_params.heightscale;

#ifdef USE_MITSHM        
          if (mit_shm_available && use_mit_shm)
            x11_window_update_method = X11_MITSHM;
          else
#endif
            x11_window_update_method = X11_NORMAL;

          switch (x11_window_update_method)
          {
#ifdef USE_MITSHM
                case X11_MITSHM:
                        /* Create a MITSHM image. */
                        fprintf (stderr, "MIT-SHM Extension Available. trying to use... ");
                        x11_mit_shm_error = 0;
                        XSetErrorHandler (x11_test_mit_shm);
                        image = XShmCreateImage (display,
                                        screen->root_visual,
                                        screen->root_depth,
                                        ZPixmap,
                                        NULL,
                                        &shm_info,
                                        image_width,
                                        image_height);
                        if (image)
                        {
                                shm_info.readOnly = False;
                                shm_info.shmid = shmget (IPC_PRIVATE,
                                                image->bytes_per_line * image->height,
                                                (IPC_CREAT | 0777));
                                if (shm_info.shmid < 0)
                                {
                                        fprintf (stderr, "\nError: failed to create MITSHM block.\n");
                                        return 1;
                                }

                                /* And allocate the bitmap buffer. */
                                image->data = shm_info.shmaddr =
                                        (char *) shmat (shm_info.shmid, 0, 0);
                                if (!image->data)
                                {
                                        fprintf (stderr, "\nError: failed to allocate MITSHM bitmap buffer.\n");
                                        return 1;
                                }

                                /* Attach the MITSHM block. this will cause an exception if */
                                /* MIT-SHM is not available. so trap it and process         */
                                if (!XShmAttach (display, &shm_info))
                                {
                                        fprintf (stderr, "\nError: failed to attach MITSHM block.\n");
                                        return 1;
                                }
                                XSync (display, False);  /* be sure to get request processed */
                                /* sleep (2);          enought time to notify error if any */
                                /* Mark segment as deletable after we attach.  When all processes
                                   detach from the segment (progam exits), it will be deleted.
                                   This way it won't be left in memory if we crash or something.
                                   Grr, have todo this after X attaches too since slowlaris doesn't
                                   like it otherwise */
                                shmctl(shm_info.shmid, IPC_RMID, NULL);

                                if (!x11_mit_shm_error)
                                {
                                        fprintf (stderr, "Success.\nUsing Shared Memory Features to speed up\n");
                                        XSetErrorHandler (None);  /* Restore error handler to default */
                                        mit_shm_attached = 1;
                                        break;
                                }
                                /* else we have failed clean up before retrying without MITSHM */
                                shmdt (shm_info.shmaddr);
                                shm_info.shmaddr = NULL;
                                XDestroyImage (image);
                                image = NULL;
                        }
                        XSetErrorHandler (None);  /* Restore error handler to default */
                        fprintf (stderr, "Failed\nReverting to normal XPutImage() mode\n");
                        x11_window_update_method = X11_NORMAL;
#endif
                case X11_NORMAL:
                        scaled_buffer_ptr=malloc(((screen->root_depth <= 16)?
                          2:4) * image_width * image_height);
                        if (!scaled_buffer_ptr)
                        {
                                fprintf (stderr, "Error: failed to allocate bitmap buffer.\n");
                                return 1;
                        }
                        image = XCreateImage (display,
                                        screen->root_visual,
                                        screen->root_depth,
                                        ZPixmap,
                                        0,
                                        scaled_buffer_ptr,
                                        image_width, image_height,
                                        32, /* image_width always is a multiple of 4 */
                                        0);

                        if (!image)
                        {
                                free (scaled_buffer_ptr);
                                fprintf (stderr, "OSD ERROR: could not create image.\n");
                                return 1;
                        }
                        break;
                default:
                        fprintf (stderr, "Error unknown X11 update method, this shouldn't happen\n");
                        return 1;
          }
          sysdep_display_properties.palette_info.bpp = image->bits_per_pixel;
        }

        /* get a blit function */
        return !(x11_window_update_display_func=sysdep_display_effect_open());
}
Exemple #15
0
XImage *
create_xshm_image (Display *dpy, Visual *visual,
		   unsigned int depth,
		   int format, XShmSegmentInfo *shm_info,
		   unsigned int width, unsigned int height)
{
#ifndef HAVE_XSHM_EXTENSION

  return create_fallback (dpy, visual, depth, format, shm_info, width, height);

#else /* HAVE_XSHM_EXTENSION */

  Status status;
  XImage *image = 0;
  if (!get_boolean_resource(dpy, "useSHM", "Boolean") ||
      !XShmQueryExtension (dpy)) {
    return create_fallback (dpy, visual, depth, format, shm_info,
                            width, height);
  }

  CATCH_X_ERROR(dpy);
  image = XShmCreateImage(dpy, visual, depth,
                          format, NULL, shm_info, width, height);
  UNCATCH_X_ERROR(dpy);
  if (shm_got_x_error)
    return create_fallback (dpy, visual, depth, format, shm_info,
                            width, height);

#ifdef DEBUG
  fprintf(stderr, "\n%s: XShmCreateImage(... %d, %d)\n", progname,
	  width, height);
#endif

  shm_info->shmid = shmget(IPC_PRIVATE,
			   image->bytes_per_line * image->height,
			   IPC_CREAT | 0777);
#ifdef DEBUG
  fprintf(stderr, "%s: shmget(IPC_PRIVATE, %d, IPC_CREAT | 0777) ==> %d\n",
	  progname, image->bytes_per_line * image->height, shm_info->shmid);
#endif

  if (shm_info->shmid == -1)
    {
      char buf[1024];
      sprintf (buf, "%s: shmget failed", progname);
      perror(buf);
      XDestroyImage (image);
      image = 0;
      XSync(dpy, False);
    }
  else
    {
      shm_info->readOnly = False;
      image->data = shm_info->shmaddr = shmat(shm_info->shmid, 0, 0);

#ifdef DEBUG
      fprintf(stderr, "%s: shmat(%d, 0, 0) ==> %d\n", progname,
	      shm_info->shmid, (int) image->data);
#endif

      CATCH_X_ERROR(dpy);
      status = XShmAttach(dpy, shm_info);
      UNCATCH_X_ERROR(dpy);
      if (shm_got_x_error)
	status = False;

      if (!status)
	{
	  fprintf (stderr, "%s: XShmAttach failed!\n", progname);
	  XDestroyImage (image);
	  XSync(dpy, False);
	  shmdt (shm_info->shmaddr);
	  image = 0;
	}
#ifdef DEBUG
      else
        fprintf(stderr, "%s: XShmAttach(dpy, shm_info) ==> True\n", progname);
#endif

      XSync(dpy, False);

      /* Delete the shared segment right now; the segment won't actually
	 go away until both the client and server have deleted it.  The
	 server will delete it as soon as the client disconnects, so we
	 should delete our side early in case of abnormal termination.
	 (And note that, in the context of xscreensaver, abnormal
	 termination is the rule rather than the exception, so this would
	 leak like a sieve if we didn't do this...)

	 #### Are we leaking anyway?  Perhaps because of the window of
	 opportunity between here and the XShmAttach call above, during
	 which we might be killed?  Do we need to establish a signal
	 handler for this case?
       */
      shmctl (shm_info->shmid, IPC_RMID, 0);

#ifdef DEBUG
      fprintf(stderr, "%s: shmctl(%d, IPC_RMID, 0)\n\n", progname,
	      shm_info->shmid);
#endif
    }

  if (!image) {
    return create_fallback (dpy, visual, depth, format, shm_info,
                            width, height);
  }

  return image;

#endif /* HAVE_XSHM_EXTENSION */
}
  /*
   * create XImage
   */
  void fastViewer::createImage(const image& img) {
    int screen;
    display_info_s& di = display_info;
    XWindowAttributes win_attributes;
    bool resizeWin = false;

    if ((di.height != img.rows()) ||
        (di.width != img.columns())) {
      resizeWin = true;
    }

    di.height = img.rows();
    di.width = img.columns();

    if (di.win == 0) {
      createWindow();
    }

    if (resizeWin) {
      XResizeWindow(di.display,di.win,di.width,di.height);
    }

    screen = DefaultScreen(di.display);
    XGetWindowAttributes(di.display, di.win, &win_attributes);
    di.depth  = win_attributes.depth;

    // TODO: maybe screen->root_depth is more precise than win_attr.depth
    //       We should try it.

    // check if the X-Server has a 32 bit interface
    if (di.depth < 24) {
      throw exception("Error: Fast Viewer works only with 32 bit depth!");
    }

    if (useShareMemory) {
      //
      // Shared Memory Setup
      //

      di.shmimage = XShmCreateImage(di.display,
                                    DefaultVisual(di.display, screen),
                                    di.depth, ZPixmap, NULL, &shminfo,
                                    di.width,
                                    di.height);

      if(isNull(di.shmimage)) {
        throw exception("fastViewer::shmimage == NULL:");
      }

      int sharedMemSize = di.shmimage->bytes_per_line * di.shmimage->height;

      shminfo.shmid = shmget(IPC_PRIVATE,
                             sharedMemSize,
                             IPC_CREAT | 0777);

      if(shminfo.shmid < 0) {
        std::string str;
        str = "fastViewer::shmget failed:";
        str += strerror(errno);

        throw exception(str);
      }

      shminfo.shmaddr = (char *) shmat(shminfo.shmid, (void *) 0, 0);
      if (shminfo.shmaddr == 0) {
        std::string str;
        str = "fastViewer::shmmat failed:";
        str += std::strerror(errno);

        throw exception(str);
      }

      di.shmimage->data = shminfo.shmaddr;

      XShmAttach(di.display, &shminfo);
      data.useExternData(di.height,di.width,(rgbPixel*)di.shmimage->data);
      data.fill(img);
    } else {
      //
      // without shared memory
      //
      const int blockSize = img.rows()*img.columns()*4;
      remoteData = new char[blockSize];
      data.useExternData(di.height,di.width,(rgbPixel*)remoteData);
      data.fill(img);

      di.shmimage = XCreateImage(di.display,
                                 DefaultVisual(di.display, screen),
                                 di.depth, ZPixmap, 0,
                                 remoteData,
                                 di.width,
                                 di.height,8,0);

      if(isNull(di.shmimage)) {
        throw exception("fastViewer::shmimage == NULL:");
      }
    }
  }
Exemple #17
0
static int video_arch_frame_buffer_alloc(video_canvas_t *canvas, unsigned int width, unsigned int height)
{
    int sizeofpixel = sizeof(BYTE);
    Display *display;
#ifdef USE_MITSHM
    int (*olderrorhandler)(Display *, XErrorEvent *);
    int dummy;
#endif

#ifdef USE_MITSHM
    canvas->using_mitshm = use_mitshm;
#endif

    display = x11ui_get_display_ptr();

    /* sizeof(PIXEL) is not always what we are using. I guess this should
       be checked from the XImage but I'm lazy... */
    if (canvas->depth > 8) {
        sizeofpixel *= 2;
    }
    if (canvas->depth > 16) {
        sizeofpixel *= 2;
    }

#ifdef HAVE_XVIDEO
    canvas->xv_image = NULL;

    if (canvas->videoconfig->hwscale) {
#if defined(__QNX__) || defined(MINIX_SUPPORT)
        XShmSegmentInfo* shminfo = NULL;
#else
        XShmSegmentInfo* shminfo = use_mitshm ? &canvas->xshm_info : NULL;
#endif

        canvas->xv_image = create_yuv_image(display, canvas->xv_port, canvas->xv_format, width, height, shminfo);
        if (!(canvas->xv_image)) {
            return -1;
        }

        /* Copy data for architecture independent rendering. */
        canvas->yuv_image.width = canvas->xv_image->width;
        canvas->yuv_image.height = canvas->xv_image->height;
        canvas->yuv_image.data_size = canvas->xv_image->data_size;
        canvas->yuv_image.num_planes = canvas->xv_image->num_planes;
        canvas->yuv_image.pitches = canvas->xv_image->pitches;
        canvas->yuv_image.offsets = canvas->xv_image->offsets;
        canvas->yuv_image.data = (unsigned char *)canvas->xv_image->data;

        log_message(x11video_log, "Successfully initialized using XVideo (%dx%d %.4s).", width, height, canvas->xv_format.label);

        return 0;
    }
#endif /* HAVE_XVIDEO */

    /* Round up to 32-bit boundary (used in XCreateImage). */
    width = (width + 3) & ~0x3;

#ifdef USE_MITSHM
tryagain:
    if (canvas->using_mitshm) {
        DEBUG_MITSHM(("frame_buffer_alloc(): allocating XImage with MITSHM, %d x %d pixels...", width, height));
        canvas->x_image = XShmCreateImage(display, visual, canvas->depth, ZPixmap, NULL, &(canvas->xshm_info), width, height);
        if (!canvas->x_image) {
            log_warning(x11video_log, "Cannot allocate XImage with XShm; falling back to non MITSHM extension mode.");
            canvas->using_mitshm = 0;
            goto tryagain;
        }
        DEBUG_MITSHM(("Done."));
        DEBUG_MITSHM(("frame_buffer_alloc(): shmgetting %ld bytes...", (long)canvas->x_image->bytes_per_line * canvas->x_image->height));
        canvas->xshm_info.shmid = shmget(IPC_PRIVATE, canvas->x_image->bytes_per_line * canvas->x_image->height, IPC_CREAT | 0604);
        if (canvas->xshm_info.shmid == -1) {
            log_warning(x11video_log, "Cannot get shared memory; falling back to non MITSHM extension mode.");
            XDestroyImage(canvas->x_image);
            canvas->using_mitshm = 0;
            goto tryagain;
        }
        DEBUG_MITSHM(("Done, id = 0x%x.", i->xshm_info.shmid));
        DEBUG_MITSHM(("frame_buffer_alloc(): getting address... "));
        canvas->xshm_info.shmaddr = shmat(canvas->xshm_info.shmid, 0, 0);
        canvas->x_image->data = canvas->xshm_info.shmaddr;
        if (canvas->xshm_info.shmaddr == (char *)-1) {
            log_warning(x11video_log, "Cannot get shared memory address; falling back to non MITSHM extension mode.");
            shmctl(canvas->xshm_info.shmid,IPC_RMID,0);
            XDestroyImage(canvas->x_image);
            canvas->using_mitshm = 0;
            goto tryagain;
        }
        DEBUG_MITSHM(("0x%lx OK.", (unsigned long) i->xshm_info.shmaddr));
        canvas->xshm_info.readOnly = True;
        mitshm_failed = 0;

        XQueryExtension(display,"MIT-SHM",&shmmajor,&dummy,&dummy);
        olderrorhandler = XSetErrorHandler(shmhandler);

        if (!XShmAttach(display, &(canvas->xshm_info))) {
            log_warning(x11video_log, "Cannot attach shared memory; falling back to non MITSHM extension mode.");
            shmdt(canvas->xshm_info.shmaddr);
            shmctl(canvas->xshm_info.shmid,IPC_RMID,0);
            XDestroyImage(canvas->x_image);
            canvas->using_mitshm = 0;
            goto tryagain;
        }

        /* Wait for XShmAttach to fail or to succede. */
        XSync(display,False);
        XSetErrorHandler(olderrorhandler);

        /* Mark memory segment for automatic deletion. */
        shmctl(canvas->xshm_info.shmid, IPC_RMID, 0);

        if (mitshm_failed) {
            log_warning(x11video_log, "Cannot attach shared memory; falling back to non MITSHM extension mode.");
            shmdt(canvas->xshm_info.shmaddr);
            XDestroyImage(canvas->x_image);
            canvas->using_mitshm = 0;
            goto tryagain;
        }

        DEBUG_MITSHM((_("MITSHM initialization succeed.\n")));
        video_refresh_func((void (*)(void))XShmPutImage);
    } else
#endif
    {                           /* !i->using_mitshm */
        char *data;

        data = lib_malloc(width * height * sizeofpixel);

        if (data == NULL) {
            return -1;
        }

        canvas->x_image = XCreateImage(display, visual, canvas->depth, ZPixmap, 0, data, width, height, 32, 0);
        if (!canvas->x_image) {
            return -1;
        }

        video_refresh_func((void (*)(void))XPutImage);
    }

#ifdef USE_MITSHM
    log_message(x11video_log, "Successfully initialized%s shared memory.", (canvas->using_mitshm) ? ", using" : " without");

    if (!(canvas->using_mitshm)) {
        log_warning(x11video_log, "Performance will be poor.");
    }
#else
    log_message(x11video_log, "Successfully initialized without shared memory.");
#endif

    return 0;
}
Exemple #18
0
/**
 * Initialize the x11 grab device demuxer (public device demuxer API).
 *
 * @param s1 Context from avformat core
 * @return <ul>
 *          <li>AVERROR(ENOMEM) no memory left</li>
 *          <li>AVERROR(EIO) other failure case</li>
 *          <li>0 success</li>
 *         </ul>
 */
static int
x11grab_read_header(AVFormatContext *s1)
{
    struct x11_grab *x11grab = s1->priv_data;
    Display *dpy;
    AVStream *st = NULL;
    enum PixelFormat input_pixfmt;
    XImage *image;
    int x_off = 0;
    int y_off = 0;
    int screen;
    int use_shm;
    char *dpyname, *offset;
    int ret = 0;
    AVRational framerate;

    dpyname = av_strdup(s1->filename);
    if (!dpyname)
        goto out;

    offset = strchr(dpyname, '+');
    if (offset) {
        sscanf(offset, "%d,%d", &x_off, &y_off);
        x11grab->draw_mouse = !strstr(offset, "nomouse");
        *offset= 0;
    }

    if ((ret = av_parse_video_size(&x11grab->width, &x11grab->height, x11grab->video_size)) < 0) {
        av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n");
        goto out;
    }
    if ((ret = av_parse_video_rate(&framerate, x11grab->framerate)) < 0) {
        av_log(s1, AV_LOG_ERROR, "Could not parse framerate: %s.\n", x11grab->framerate);
        goto out;
    }
    av_log(s1, AV_LOG_INFO, "device: %s -> display: %s x: %d y: %d width: %d height: %d\n",
           s1->filename, dpyname, x_off, y_off, x11grab->width, x11grab->height);

    dpy = XOpenDisplay(dpyname);
    av_freep(&dpyname);
    if(!dpy) {
        av_log(s1, AV_LOG_ERROR, "Could not open X display.\n");
        ret = AVERROR(EIO);
        goto out;
    }

    st = avformat_new_stream(s1, NULL);
    if (!st) {
        ret = AVERROR(ENOMEM);
        goto out;
    }
    avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */

    screen = DefaultScreen(dpy);

    if (x11grab->follow_mouse) {
        int screen_w, screen_h;
        Window w;

        screen_w = DisplayWidth(dpy, screen);
        screen_h = DisplayHeight(dpy, screen);
        XQueryPointer(dpy, RootWindow(dpy, screen), &w, &w, &x_off, &y_off, &ret, &ret, &ret);
        x_off -= x11grab->width / 2;
        y_off -= x11grab->height / 2;
        x_off = FFMIN(FFMAX(x_off, 0), screen_w - x11grab->width);
        y_off = FFMIN(FFMAX(y_off, 0), screen_h - x11grab->height);
        av_log(s1, AV_LOG_INFO, "followmouse is enabled, resetting grabbing region to x: %d y: %d\n", x_off, y_off);
    }

    use_shm = XShmQueryExtension(dpy);
    av_log(s1, AV_LOG_INFO, "shared memory extension%s found\n", use_shm ? "" : " not");

    if(use_shm) {
        int scr = XDefaultScreen(dpy);
        image = XShmCreateImage(dpy,
                                DefaultVisual(dpy, scr),
                                DefaultDepth(dpy, scr),
                                ZPixmap,
                                NULL,
                                &x11grab->shminfo,
                                x11grab->width, x11grab->height);
        x11grab->shminfo.shmid = shmget(IPC_PRIVATE,
                                        image->bytes_per_line * image->height,
                                        IPC_CREAT|0777);
        if (x11grab->shminfo.shmid == -1) {
            av_log(s1, AV_LOG_ERROR, "Fatal: Can't get shared memory!\n");
            ret = AVERROR(ENOMEM);
            goto out;
        }
        x11grab->shminfo.shmaddr = image->data = shmat(x11grab->shminfo.shmid, 0, 0);
        x11grab->shminfo.readOnly = False;

        if (!XShmAttach(dpy, &x11grab->shminfo)) {
            av_log(s1, AV_LOG_ERROR, "Fatal: Failed to attach shared memory!\n");
            /* needs some better error subroutine :) */
            ret = AVERROR(EIO);
            goto out;
        }
    } else {
        image = XGetImage(dpy, RootWindow(dpy, screen),
                          x_off,y_off,
                          x11grab->width, x11grab->height,
                          AllPlanes, ZPixmap);
    }

    switch (image->bits_per_pixel) {
    case 8:
        av_log (s1, AV_LOG_DEBUG, "8 bit palette\n");
        input_pixfmt = PIX_FMT_PAL8;
        break;
    case 16:
        if (       image->red_mask   == 0xf800 &&
                   image->green_mask == 0x07e0 &&
                   image->blue_mask  == 0x001f ) {
            av_log (s1, AV_LOG_DEBUG, "16 bit RGB565\n");
            input_pixfmt = PIX_FMT_RGB565;
        } else if (image->red_mask   == 0x7c00 &&
                   image->green_mask == 0x03e0 &&
                   image->blue_mask  == 0x001f ) {
            av_log(s1, AV_LOG_DEBUG, "16 bit RGB555\n");
            input_pixfmt = PIX_FMT_RGB555;
        } else {
            av_log(s1, AV_LOG_ERROR, "RGB ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel);
            av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask);
            ret = AVERROR(EIO);
            goto out;
        }
        break;
    case 24:
        if (        image->red_mask   == 0xff0000 &&
                    image->green_mask == 0x00ff00 &&
                    image->blue_mask  == 0x0000ff ) {
            input_pixfmt = PIX_FMT_BGR24;
        } else if ( image->red_mask   == 0x0000ff &&
                    image->green_mask == 0x00ff00 &&
                    image->blue_mask  == 0xff0000 ) {
            input_pixfmt = PIX_FMT_RGB24;
        } else {
            av_log(s1, AV_LOG_ERROR,"rgb ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel);
            av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask);
            ret = AVERROR(EIO);
            goto out;
        }
        break;
    case 32:
        input_pixfmt = PIX_FMT_0RGB32;
        break;
    default:
        av_log(s1, AV_LOG_ERROR, "image depth %i not supported ... aborting\n", image->bits_per_pixel);
        ret = AVERROR(EINVAL);
        goto out;
    }

    x11grab->frame_size = x11grab->width * x11grab->height * image->bits_per_pixel/8;
    x11grab->dpy = dpy;
    x11grab->time_base  = (AVRational){framerate.den, framerate.num};
    x11grab->time_frame = av_gettime() / av_q2d(x11grab->time_base);
    x11grab->x_off = x_off;
    x11grab->y_off = y_off;
    x11grab->image = image;
    x11grab->use_shm = use_shm;

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id = CODEC_ID_RAWVIDEO;
    st->codec->width  = x11grab->width;
    st->codec->height = x11grab->height;
    st->codec->pix_fmt = input_pixfmt;
    st->codec->time_base = x11grab->time_base;
    st->codec->bit_rate = x11grab->frame_size * 1/av_q2d(x11grab->time_base) * 8;

out:
    av_free(dpyname);
    return ret;
}
Exemple #19
0
DFBResult
dfb_x11_image_init_handler( DFBX11 *x11, x11Image *image )
{
     Visual *visual;
     XImage *ximage;

     D_MAGIC_ASSERT( image, x11Image );

     if (!x11->use_shm)
          return DFB_UNSUPPORTED;

     /* Lookup visual. */
     visual = x11->visuals[DFB_PIXELFORMAT_INDEX(image->format)];
     if (!visual)
          return DFB_UNSUPPORTED;

     image->visual = visual;

     XLockDisplay( x11->display );

     ximage = XShmCreateImage( x11->display, image->visual, image->depth,
                               ZPixmap, NULL, &image->seginfo, image->width, image->height );
     if (!ximage) {
          D_ERROR( "X11/ShmImage: Error creating shared image (XShmCreateImage)!\n");
          XUnlockDisplay( x11->display );
          return DFB_FAILURE;
     }

     /* we firstly create our shared memory segment with the size we need, and
      correct permissions for the owner, the group and the world --> 0777 */
     image->seginfo.shmid = shmget( IPC_PRIVATE, 
                                    ximage->bytes_per_line * ximage->height,
                                    IPC_CREAT | 0777 );
     if (image->seginfo.shmid < 0)
          goto error;

     /* Then, we have to attach the segment to our process, and we let the
        function search the correct memory place --> NULL. It's safest ! */
     image->seginfo.shmaddr = shmat( image->seginfo.shmid, NULL, 0 );
     if (!image->seginfo.shmaddr)
          goto error_shmat;

     ximage->data = image->seginfo.shmaddr;

     /* We set the buffer in Read and Write mode */
     image->seginfo.readOnly = False;

     if (!XShmAttach( x11->display, &image->seginfo ))
          goto error_xshmattach;

     image->ximage = ximage;
     image->pitch  = ximage->bytes_per_line;

     image->pixmap = XShmCreatePixmap( x11->display, DefaultRootWindow(x11->display), ximage->data,
                                       &image->seginfo, image->width, image->height, image->depth );

     image->gc = XCreateGC( x11->display, image->pixmap, 0, NULL );

     XUnlockDisplay( x11->display );

     return DFB_OK;


error_xshmattach:
     shmdt( image->seginfo.shmaddr );

error_shmat:
     shmctl( image->seginfo.shmid, IPC_RMID, NULL );

error:
     XDestroyImage( ximage );

     XUnlockDisplay( x11->display );

     return DFB_FAILURE;
}
Exemple #20
0
static inline int up_x11mapsharedmem(int depth, unsigned int fblen)
{
#ifndef CONFIG_SIM_X11NOSHM
  Status result;
#endif

  atexit(up_x11uninitX);
  g_shmcheckpoint = 1;
  b_useshm = 0;

#ifndef CONFIG_SIM_X11NOSHM
  if (XShmQueryExtension(g_display))
    {
      b_useshm = 1;
      printf("Using shared memory.\n");

      up_x11traperrors();
      g_image = XShmCreateImage(g_display, DefaultVisual(g_display, g_screen), 
                                depth, ZPixmap, NULL, &g_xshminfo,
                                g_fbpixelwidth, g_fbpixelheight);
      if (up_x11untraperrors())
        {
          up_x11uninitialize();
          goto shmerror;
        }
      if (!g_image)
        {
          fprintf(stderr,"Unable to create g_image.");
          return -1;
        }
      g_shmcheckpoint++;

      g_xshminfo.shmid = shmget(IPC_PRIVATE,
                              g_image->bytes_per_line * g_image->height,
                              IPC_CREAT | 0777);
      if (g_xshminfo.shmid < 0)
        {
          up_x11uninitialize();
          goto shmerror;
        }
      g_shmcheckpoint++;

      g_image->data = (char *) shmat(g_xshminfo.shmid, 0, 0);
      if (g_image->data == ((char *) -1))
        {
          up_x11uninitialize();
          goto shmerror;
        }
      g_shmcheckpoint++;

      g_xshminfo.shmaddr = g_image->data;
      g_xshminfo.readOnly = 0;

      up_x11traperrors();
      result = XShmAttach(g_display, &g_xshminfo);
      if (up_x11untraperrors() || !result)
        {
          up_x11uninitialize();
          goto shmerror;
        }

      g_shmcheckpoint++;

    }
  else
#endif
  if (!b_useshm)
    {
#ifndef CONFIG_SIM_X11NOSHM
shmerror:
#endif
      b_useshm = 0;

      g_framebuffer = (unsigned char*)malloc(fblen);

      g_image = XCreateImage(g_display, DefaultVisual(g_display,g_screen), depth,
                             ZPixmap, 0, (char*)g_framebuffer, g_fbpixelwidth, g_fbpixelheight,
                             8, 0);

      if (g_image == NULL)
         {
            fprintf(stderr, "Unable to create g_image\n");
            return -1;
         }

      g_shmcheckpoint++;
    }
  return 0;
}
Exemple #21
0
static void getMyXImage(void)
{
#ifdef HAVE_SHM
    if (mLocalDisplay && XShmQueryExtension(mDisplay))
        Shmem_Flag = 1;
    else
    {
        Shmem_Flag = 0;
        mp_msg(MSGT_VO, MSGL_WARN,
               "Shared memory not supported\nReverting to normal Xlib\n");
    }
    if (Shmem_Flag)
        CompletionType = XShmGetEventBase(mDisplay) + ShmCompletion;

    if (Shmem_Flag)
    {
        myximage =
            XShmCreateImage(mDisplay, vinfo.visual, depth, ZPixmap, NULL,
                            &Shminfo[0], image_width, image_height);
        if (myximage == NULL)
        {
            mp_msg(MSGT_VO, MSGL_WARN,
                   "Shared memory error,disabling ( Ximage error )\n");
            goto shmemerror;
        }
        Shminfo[0].shmid = shmget(IPC_PRIVATE,
                                  myximage->bytes_per_line *
                                  myximage->height, IPC_CREAT | 0777);
        if (Shminfo[0].shmid < 0)
        {
            XDestroyImage(myximage);
            mp_msg(MSGT_VO, MSGL_V, "%s\n", strerror(errno));
            //perror( strerror( errno ) );
            mp_msg(MSGT_VO, MSGL_WARN,
                   "Shared memory error,disabling ( seg id error )\n");
            goto shmemerror;
        }
        Shminfo[0].shmaddr = (char *) shmat(Shminfo[0].shmid, 0, 0);

        if (Shminfo[0].shmaddr == ((char *) -1))
        {
            XDestroyImage(myximage);
            if (Shminfo[0].shmaddr != ((char *) -1))
                shmdt(Shminfo[0].shmaddr);
            mp_msg(MSGT_VO, MSGL_WARN,
                   "Shared memory error,disabling ( address error )\n");
            goto shmemerror;
        }
        myximage->data = Shminfo[0].shmaddr;
        ImageData = (unsigned char *) myximage->data;
        Shminfo[0].readOnly = False;
        XShmAttach(mDisplay, &Shminfo[0]);

        XSync(mDisplay, False);

        if (gXErrorFlag)
        {
            XDestroyImage(myximage);
            shmdt(Shminfo[0].shmaddr);
            mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling.\n");
            gXErrorFlag = 0;
            goto shmemerror;
        } else
            shmctl(Shminfo[0].shmid, IPC_RMID, 0);

        {
            static int firstTime = 1;

            if (firstTime)
            {
                mp_msg(MSGT_VO, MSGL_V, "Sharing memory.\n");
                firstTime = 0;
            }
        }
    } else
    {
      shmemerror:
        Shmem_Flag = 0;
#endif
        myximage = XCreateImage(mDisplay, vinfo.visual, depth, ZPixmap,
                             0, NULL, image_width, image_height, 8, 0);
        ImageDataOrig = malloc(myximage->bytes_per_line * image_height + 32);
        myximage->data = ImageDataOrig + 16 - ((long)ImageDataOrig & 15);
        memset(myximage->data, 0, myximage->bytes_per_line * image_height);
        ImageData = myximage->data;
#ifdef HAVE_SHM
    }
#endif
}
Exemple #22
0
/**
 * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
 * Return:  GL_TRUE if success, GL_FALSE if error
 */
static GLboolean
alloc_back_shm_ximage(XMesaBuffer b, GLuint width, GLuint height)
{
    /*
     * We have to do a _lot_ of error checking here to be sure we can
     * really use the XSHM extension.  It seems different servers trigger
     * errors at different points if the extension won't work.  Therefore
     * we have to be very careful...
     */
    GC gc;
    int (*old_handler)(XMesaDisplay *, XErrorEvent *);

    if (width == 0 || height == 0) {
        /* this will be true the first time we're called on 'b' */
        return GL_FALSE;
    }

    b->backxrb->ximage = XShmCreateImage(b->xm_visual->display,
                                         b->xm_visual->visinfo->visual,
                                         b->xm_visual->visinfo->depth,
                                         ZPixmap, NULL, &b->shminfo,
                                         width, height);
    if (b->backxrb->ximage == NULL) {
        _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.\n");
        b->shm = 0;
        return GL_FALSE;
    }

    b->shminfo.shmid = shmget(IPC_PRIVATE, b->backxrb->ximage->bytes_per_line
                              * b->backxrb->ximage->height, IPC_CREAT|0777);
    if (b->shminfo.shmid < 0) {
        _mesa_warning(NULL, "shmget failed while allocating back buffer.\n");
        XDestroyImage(b->backxrb->ximage);
        b->backxrb->ximage = NULL;
        _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling.\n");
        b->shm = 0;
        return GL_FALSE;
    }

    b->shminfo.shmaddr = b->backxrb->ximage->data
                         = (char*)shmat(b->shminfo.shmid, 0, 0);
    if (b->shminfo.shmaddr == (char *) -1) {
        _mesa_warning(NULL, "shmat() failed while allocating back buffer.\n");
        XDestroyImage(b->backxrb->ximage);
        shmctl(b->shminfo.shmid, IPC_RMID, 0);
        b->backxrb->ximage = NULL;
        _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling.\n");
        b->shm = 0;
        return GL_FALSE;
    }

    b->shminfo.readOnly = False;
    mesaXErrorFlag = 0;
    old_handler = XSetErrorHandler(mesaHandleXError);
    /* This may trigger the X protocol error we're ready to catch: */
    XShmAttach(b->xm_visual->display, &b->shminfo);
    XSync(b->xm_visual->display, False);

    if (mesaXErrorFlag) {
        /* we are on a remote display, this error is normal, don't print it */
        XFlush(b->xm_visual->display);
        mesaXErrorFlag = 0;
        XDestroyImage(b->backxrb->ximage);
        shmdt(b->shminfo.shmaddr);
        shmctl(b->shminfo.shmid, IPC_RMID, 0);
        b->backxrb->ximage = NULL;
        b->shm = 0;
        (void) XSetErrorHandler(old_handler);
        return GL_FALSE;
    }

    shmctl(b->shminfo.shmid, IPC_RMID, 0); /* nobody else needs it */

    /* Finally, try an XShmPutImage to be really sure the extension works */
    gc = XCreateGC(b->xm_visual->display, b->frontxrb->drawable, 0, NULL);
    XShmPutImage(b->xm_visual->display, b->frontxrb->drawable, gc,
                 b->backxrb->ximage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False);
    XSync(b->xm_visual->display, False);
    XFreeGC(b->xm_visual->display, gc);
    (void) XSetErrorHandler(old_handler);
    if (mesaXErrorFlag) {
        XFlush(b->xm_visual->display);
        mesaXErrorFlag = 0;
        XDestroyImage(b->backxrb->ximage);
        shmdt(b->shminfo.shmaddr);
        shmctl(b->shminfo.shmid, IPC_RMID, 0);
        b->backxrb->ximage = NULL;
        b->shm = 0;
        return GL_FALSE;
    }

    return GL_TRUE;
}
Exemple #23
0
Bool
dfb_x11_open_window( DFBX11 *x11, XWindow** ppXW, int iXPos, int iYPos, int iWidth, int iHeight, DFBSurfacePixelFormat format )
{
     XWindow              *xw;
     XSetWindowAttributes  attr = { .background_pixmap = 0 };
     void                 *old_error_handler = 0;
     unsigned int          cw_mask = CWEventMask;

     D_DEBUG_AT( X11_Window, "Creating %4dx%4d %s window...\n", iWidth, iHeight, dfb_pixelformat_name(format) );

     xw = D_CALLOC( 1, sizeof(XWindow) );
     if (!xw)
          return D_OOM();

     /* We set the structure as needed for our window */
     xw->width   = iWidth;
     xw->height  = iHeight;
     xw->display = x11->display;

     xw->screenptr = DefaultScreenOfDisplay(xw->display);
     xw->screennum = DefaultScreen(xw->display);
     xw->depth     = DefaultDepthOfScreen(xw->screenptr);
     xw->visual    = DefaultVisualOfScreen(xw->screenptr);

     attr.event_mask =
            ButtonPressMask
          | ButtonReleaseMask
          | PointerMotionMask
          | KeyPressMask
          | KeyReleaseMask
          | ExposureMask
          | StructureNotifyMask;

     if (dfb_config->x11_borderless) {
          attr.override_redirect = True;

          cw_mask |= CWOverrideRedirect;
     }

     XLockDisplay( x11->display );

     old_error_handler = XSetErrorHandler( error_handler );

     error_code = 0;

     xw->window = XCreateWindow( xw->display,
                                 RootWindowOfScreen(xw->screenptr),
                                 iXPos, iYPos, iWidth, iHeight, 0, xw->depth, InputOutput,
                                 xw->visual, cw_mask, &attr );
     XSync( xw->display, False );
     if (!xw->window || error_code) {
          D_FREE( xw );
          XUnlockDisplay( x11->display );
          return False;
     }


     XSizeHints Hints;

     /*
      * Here we inform the function of what we are going to change for the
      * window (there's also PPosition but it's obsolete)
      */
     Hints.flags    =    PSize | PMinSize | PMaxSize;

     /*
      * Now we set the structure to the values we need for width & height.
      * For esthetic reasons we set Width=MinWidth=MaxWidth.
      * The same goes for Height. You can try whith differents values, or
      * let's use Hints.flags=Psize; and resize your window..
      */
     Hints.min_width          =    Hints.max_width          =    Hints.base_width    =    xw->width;
     Hints.min_height    =    Hints.max_height    =    Hints.base_height   =    xw->height;

     /* Now we can set the size hints for the specified window */
     XSetWMNormalHints(xw->display,xw->window,&Hints);

     /* We change the title of the window (default:Untitled) */
     XStoreName(xw->display,xw->window,"DFB X11 system window");

     xw->gc = XCreateGC(xw->display, xw->window, 0, NULL);

#if 0
     // Create a null cursor
     Pixmap  pixmp1;
     Pixmap  pixmp2;
     XColor  fore;
     XColor  back;
     char    zero = 0;

     pixmp1 = XCreateBitmapFromData( xw->display, xw->window, &zero, 1, 1 );
     pixmp2 = XCreateBitmapFromData( xw->display, xw->window, &zero, 1, 1 );

     xw->NullCursor = XCreatePixmapCursor( xw->display, pixmp1, pixmp2, &fore, &back, 0, 0 );

     XFreePixmap ( xw->display, pixmp1 );
     XFreePixmap ( xw->display, pixmp2 );

     XDefineCursor( xw->display, xw->window, xw->NullCursor );
#endif

     /* maps the window and raises it to the top of the stack */
     XMapRaised( xw->display, xw->window );


     if (x11->use_shm) {
          // Shared memory
          xw->shmseginfo=(XShmSegmentInfo *)D_CALLOC(1, sizeof(XShmSegmentInfo));
          if (!xw->shmseginfo) {
               x11->use_shm = false;
               goto no_shm;
          }

          xw->ximage=XShmCreateImage(xw->display, xw->visual, xw->depth, ZPixmap,
                                     NULL,xw->shmseginfo, xw->width, xw->height * 2);
          XSync( xw->display, False );
          if (!xw->ximage || error_code) {
               D_ERROR("X11: Error creating shared image (XShmCreateImage) \n");
               x11->use_shm = false;
               D_FREE(xw->shmseginfo);
               error_code = 0;
               goto no_shm;
          }

          xw->bpp = (xw->ximage->bits_per_pixel + 7) / 8;

          /* we firstly create our shared memory segment with the size we need, and
          correct permissions for the owner, the group and the world --> 0777 */
          xw->shmseginfo->shmid=shmget(IPC_PRIVATE,
                                       xw->ximage->bytes_per_line * xw->ximage->height * 2,
                                       IPC_CREAT|0777);

          if (xw->shmseginfo->shmid<0) {
               x11->use_shm = false;
               XDestroyImage(xw->ximage);
               D_FREE(xw->shmseginfo);
               goto no_shm;
          }

          /* Then, we have to attach the segment to our process, and we let the
          function search the correct memory place --> NULL. It's safest ! */
          xw->shmseginfo->shmaddr = shmat( xw->shmseginfo->shmid, NULL, 0 );
          if (!xw->shmseginfo->shmaddr) {
               x11->use_shm = false;
               shmctl(xw->shmseginfo->shmid,IPC_RMID,NULL);
               XDestroyImage(xw->ximage);
               D_FREE(xw->shmseginfo);
               goto no_shm;
          }

          /* We set the buffer in Read and Write mode */
          xw->shmseginfo->readOnly=False;

          xw->virtualscreen= xw->ximage->data = xw->shmseginfo->shmaddr;


          XSetErrorHandler( error_handler_shm );

          XShmAttach(x11->display,xw->shmseginfo);

          XShmPutImage(x11->display, xw->window, xw->gc, xw->ximage,
                       0, 0, 0, 0, 1, 1, False);

          XSync(x11->display, False);

          XSetErrorHandler( error_handler );

          if (!x11->use_shm) {
               shmdt(xw->shmseginfo->shmaddr);
               shmctl(xw->shmseginfo->shmid,IPC_RMID,NULL);
               XDestroyImage(xw->ximage);
               D_FREE(xw->shmseginfo);
          }
     }

no_shm:
     if (!x11->use_shm) {
          int pitch;

          xw->bpp = (xw->depth > 16) ? 4 :
                    (xw->depth >  8) ? 2 : 1;

          pitch = (xw->bpp * xw->width + 3) & ~3;

          /* Use malloc(), not D_MALLOC() here, because XCreateImage()
           * will call free() on this data.
           */
          xw->virtualscreen = malloc ( 2 * xw->height * pitch );

          xw->ximage = XCreateImage( xw->display, xw->visual, xw->depth, ZPixmap, 0,
                                     xw->virtualscreen, xw->width, xw->height * 2, 32, pitch );
          XSync( xw->display, False );
          if (!xw->ximage || error_code) {
               D_ERROR( "X11/Window: XCreateImage( Visual %02lu, depth %d, size %dx%d, buffer %p [%d] ) failed!\n",
                        xw->visual->visualid, xw->depth, xw->width, xw->height * 2, xw->virtualscreen, pitch );
               XFreeGC(xw->display,xw->gc);
               XDestroyWindow(xw->display,xw->window);
               XSetErrorHandler( old_error_handler );
               XUnlockDisplay( x11->display );
               D_FREE( xw );
               return False;
          }
     }

     XSetErrorHandler( old_error_handler );

     XUnlockDisplay( x11->display );

     D_INFO( "X11/Display: %ssing XShm.\n", x11->use_shm ? "U" : "Not u" );

     (*ppXW) = xw;

     return True;
}

void
dfb_x11_close_window( DFBX11 *x11, XWindow* xw )
{
     if (x11->use_shm) {
          XShmDetach( xw->display, xw->shmseginfo );
          shmdt( xw->shmseginfo->shmaddr );
          shmctl( xw->shmseginfo->shmid, IPC_RMID, NULL );
          D_FREE( xw->shmseginfo );
     }

     XDestroyImage( xw->ximage );

     XFreeGC( xw->display, xw->gc );
     XDestroyWindow( xw->display, xw->window );
#if 0
     XFreeCursor( xw->display, xw->NullCursor );
#endif

     D_FREE( xw );
}
Exemple #24
0
static bool getMyXImage(struct priv *p, int foo)
{
    struct vo *vo = p->vo;
#if HAVE_SHM && HAVE_XEXT
    if (vo->x11->display_is_local && XShmQueryExtension(vo->x11->display)) {
        p->Shmem_Flag = 1;
        vo->x11->ShmCompletionEvent = XShmGetEventBase(vo->x11->display)
                                    + ShmCompletion;
    } else {
        p->Shmem_Flag = 0;
        MP_WARN(vo, "Shared memory not supported\nReverting to normal Xlib\n");
    }

    if (p->Shmem_Flag) {
        p->myximage[foo] =
            XShmCreateImage(vo->x11->display, p->vinfo.visual, p->depth,
                            ZPixmap, NULL, &p->Shminfo[foo], p->image_width,
                            p->image_height);
        if (p->myximage[foo] == NULL) {
            MP_WARN(vo, "Shared memory error,disabling ( Ximage error )\n");
            goto shmemerror;
        }
        p->Shminfo[foo].shmid = shmget(IPC_PRIVATE,
                                       p->myximage[foo]->bytes_per_line *
                                       p->myximage[foo]->height,
                                       IPC_CREAT | 0777);
        if (p->Shminfo[foo].shmid < 0) {
            XDestroyImage(p->myximage[foo]);
            MP_WARN(vo, "Shared memory error,disabling ( seg id error )\n");
            goto shmemerror;
        }
        p->Shminfo[foo].shmaddr = (char *) shmat(p->Shminfo[foo].shmid, 0, 0);

        if (p->Shminfo[foo].shmaddr == ((char *) -1)) {
            XDestroyImage(p->myximage[foo]);
            MP_WARN(vo, "Shared memory error,disabling ( address error )\n");
            goto shmemerror;
        }
        p->myximage[foo]->data = p->Shminfo[foo].shmaddr;
        p->Shminfo[foo].readOnly = False;
        XShmAttach(vo->x11->display, &p->Shminfo[foo]);

        XSync(vo->x11->display, False);

        shmctl(p->Shminfo[foo].shmid, IPC_RMID, 0);
    } else {
shmemerror:
        p->Shmem_Flag = 0;
#endif
    MP_VERBOSE(vo, "Not using SHM.\n");
    p->myximage[foo] =
        XCreateImage(vo->x11->display, p->vinfo.visual, p->depth, ZPixmap,
                     0, NULL, p->image_width, p->image_height, 8, 0);
    if (!p->myximage[foo]) {
        MP_WARN(vo, "could not allocate image");
        return false;
    }
    p->myximage[foo]->data =
        calloc(1, p->myximage[foo]->bytes_per_line * p->image_height + 32);
#if HAVE_SHM && HAVE_XEXT
}
#endif
    return true;
}
Exemple #25
0
static void SetupImage (void)
{
	TakedownImage();

#ifdef MITSHM
	GUI.use_shared_memory = TRUE;

	int		major, minor;
	Bool	shared;

	if (!XShmQueryVersion(GUI.display, &major, &minor, &shared) || !shared)
		GUI.image = NULL;
	else
		GUI.image = XShmCreateImage(GUI.display, GUI.visual, GUI.depth, ZPixmap, NULL, &GUI.sm_info, SNES_WIDTH * 2, SNES_HEIGHT_EXTENDED * 2);

	if (!GUI.image)
		GUI.use_shared_memory = FALSE;
	else
	{
		GUI.sm_info.shmid = shmget(IPC_PRIVATE, GUI.image->bytes_per_line * GUI.image->height, IPC_CREAT | 0777);
		if (GUI.sm_info.shmid < 0)
		{
			XDestroyImage(GUI.image);
			GUI.use_shared_memory = FALSE;
		}
		else
		{
			GUI.image->data = GUI.sm_info.shmaddr = (char *) shmat(GUI.sm_info.shmid, 0, 0);
			if (!GUI.image->data)
			{
				XDestroyImage(GUI.image);
				shmctl(GUI.sm_info.shmid, IPC_RMID, 0);
				GUI.use_shared_memory = FALSE;
			}
			else
			{
				GUI.sm_info.readOnly = False;

				XSetErrorHandler(ErrorHandler);
				XShmAttach(GUI.display, &GUI.sm_info);
				XSync(GUI.display, False);

				// X Error handler might clear GUI.use_shared_memory if XShmAttach failed.
				if (!GUI.use_shared_memory)
				{
					XDestroyImage(GUI.image);
					shmdt(GUI.sm_info.shmaddr);
					shmctl(GUI.sm_info.shmid, IPC_RMID, 0);
				}
			}
		}
	}

	if (!GUI.use_shared_memory)
	{
		fprintf(stderr, "use_shared_memory failed, switching to XPutImage.\n");
#endif
		GUI.image = XCreateImage(GUI.display, GUI.visual, GUI.depth, ZPixmap, 0, NULL, SNES_WIDTH * 2, SNES_HEIGHT_EXTENDED * 2, BitmapUnit(GUI.display), 0);
		GUI.image->data = (char *) malloc(GUI.image->bytes_per_line * GUI.image->height);
		if (!GUI.image || !GUI.image->data)
			FatalError("XCreateImage failed.");
#ifdef MITSHM
	}
#endif

#ifdef LSB_FIRST
	GUI.image->byte_order = LSBFirst;
#else
	GUI.image->byte_order = MSBFirst;
#endif

	GFX.Pitch = SNES_WIDTH * 2 * 2;
	GUI.snes_buffer = (uint8 *) calloc(GFX.Pitch * ((SNES_HEIGHT_EXTENDED + 4) * 2), 1);
	if (!GUI.snes_buffer)
		FatalError("Failed to allocate GUI.snes_buffer.");

	GFX.Screen = (uint16 *) (GUI.snes_buffer + (GFX.Pitch * 2 * 2));

	GUI.filter_buffer = (uint8 *) calloc((SNES_WIDTH * 2) * 2 * (SNES_HEIGHT_EXTENDED * 2), 1);
	if (!GUI.filter_buffer)
		FatalError("Failed to allocate GUI.filter_buffer.");

	if (GUI.depth == 15 || GUI.depth == 16)
	{
		GUI.blit_screen_pitch = GUI.image->bytes_per_line;
		GUI.blit_screen       = (uint8 *) GUI.image->data;
		GUI.need_convert      = FALSE;
	}
	else
	{
		GUI.blit_screen_pitch = (SNES_WIDTH * 2) * 2;
		GUI.blit_screen       = GUI.filter_buffer;
		GUI.need_convert      = TRUE;
	}

	S9xGraphicsInit();
}
uint32_t *GetX11(uint16_t x, uint16_t y, uint16_t *w, uint16_t *h){
	xGetImageReply rep;
	xGetImageReq *req;
	long nbytes;

	if(!image){
		return 0;
	}
	XGetWindowAttributes(dpy, CaptureWin, &gwa);

	if(image->width != gwa.width || image->height != gwa.height){
		printf("X11 Window: Changed W/H\n");
		*w = gwa.width;
		*h = gwa.height;
		XFree(image);
#ifdef X11_USE_XSHM_
		if(use_shm) {
			int scr = XDefaultScreen(dpy);
			image = XShmCreateImage(dpy,
						DefaultVisual(dpy, scr),
						DefaultDepth(dpy, scr),
						ZPixmap,
						NULL,
						&shminfo,
						w, h);
			shminfo.shmid = shmget(	IPC_PRIVATE,
						image->bytes_per_line * image->height,
						IPC_CREAT|0777);
			if(shminfo.shmid == -1){
				printf("shminfo.shmid == -1\n");
				return 0;
			}
			shminfo.shmaddr = image->data = (char*) shmat(shminfo.shmid, 0, 0);
			shminfo.readOnly = False;

			if(!XShmAttach(dpy, &shminfo)){
				printf("!XShmAttach(dpy, &shminfo)\n");
				return 0;
			}
		}
		else{
#endif /*X11_USE_XSHM_*/
			image = XGetImage(dpy, CaptureWin,
					  x,y,
					  gwa.width,gwa.height,
					  AllPlanes, ZPixmap);
#ifdef X11_USE_XSHM_
		}
#endif /*X11_USE_XSHM_*/
	}

	/* Here i should add a check to be sure that the window is still open */
	LockDisplay(dpy);
	GetReq(GetImage, req);

	req->drawable = CaptureWin;
	req->x = x;
	req->y = y;
	req->width = gwa.width;
	req->height = gwa.height;
	req->planeMask = (unsigned int)AllPlanes;
	req->format = ZPixmap;

	if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.length) {
		UnlockDisplay(dpy);
		SyncHandle();
		return 0;
	}

	nbytes = (long)rep.length << 2;
	_XReadPad(dpy, image->data, nbytes);

	UnlockDisplay(dpy);
	SyncHandle();

	return (uint32_t*) image->data;
}
void *vs_open (int v_width, int v_height)
{
	Ctx *ctx = malloc(sizeof(Ctx));
	ctx->v_width = v_width;
	ctx->v_height = v_height;

	// window
	ctx->display = XOpenDisplay(0);
	if (!ctx->display) {
		fprintf(stderr, "%s: XOpenDisplay err\n", __func__);
		exit(-1);
	}
	ctx->window = XCreateSimpleWindow(ctx->display, RootWindow(ctx->display, 0),
			100, 100, v_width, v_height, 0, BlackPixel(ctx->display, 0),
			WhitePixel(ctx->display, 0));
	ctx->screen = 0;
	ctx->gc = XCreateGC(ctx->display, ctx->window, 0, 0);
	
	XMapWindow(ctx->display, ctx->window);

	// current screen pix fmt
	Window root;
	unsigned int cx, cy, border, depth;
	int x, y;
	XGetGeometry(ctx->display, ctx->window, &root, &x, &y, &cx, &cy, &border, &depth);

	// visual info
	XMatchVisualInfo(ctx->display, ctx->screen, depth, DirectColor, &ctx->vinfo);

	// image
	ctx->image = XShmCreateImage(ctx->display, ctx->vinfo.visual, depth, ZPixmap, 0,
			&ctx->segment, cx, cy);
	if (!ctx->image) {
		fprintf(stderr, "%s: can't XShmCreateImage !\n", __func__);
		exit(-1);
	}
	ctx->segment.shmid = shmget(IPC_PRIVATE,
			ctx->image->bytes_per_line * ctx->image->height, 
			IPC_CREAT | 0777);
	if (ctx->segment.shmid < 0) {
		fprintf(stderr, "%s: shmget err\n", __func__);
		exit(-1);
	}

	ctx->segment.shmaddr = (char*)shmat(ctx->segment.shmid, 0, 0);
	if (ctx->segment.shmaddr == (char*)-1) {
		fprintf(stderr, "%s: shmat err\n", __func__);
		exit(-1);
	}

	ctx->image->data = ctx->segment.shmaddr;
	ctx->segment.readOnly = 0;
	XShmAttach(ctx->display, &ctx->segment);

	PixelFormat target_pix_fmt = PIX_FMT_NONE;
	switch (ctx->image->bits_per_pixel) {
		case 32:
			target_pix_fmt = PIX_FMT_RGB32;
			break;
		case 24:
			target_pix_fmt = PIX_FMT_RGB24;
			break;
		default:
			break;
	}

	if (target_pix_fmt == PIX_FMT_NONE) {
		fprintf(stderr, "%s: screen depth format err\n", __func__);
		free(ctx);
		return 0;
	}

	// sws
	ctx->target_pixfmt = target_pix_fmt;
	ctx->curr_width = cx;
	ctx->curr_height = cy;
	ctx->sws = sws_getContext(v_width, v_height, PIX_FMT_YUV420P,
			cx, cy, target_pix_fmt,
			SWS_FAST_BILINEAR, 0, 0, 0);

	avpicture_alloc(&ctx->pic_target, target_pix_fmt, cx, cy);

	XFlush(ctx->display);

	return ctx;
}
Exemple #28
0
int image_create( IMAGE_CONTEXT *img_ctx, int width, int height )
{
	XGCValues          gcValues;
	ulong              gcValuesMask;
	XWindowAttributes  windowAttributes;


	/*if ( img_ctx->xImage != NULL )
        image_destroy( img_ctx );*/

    g_width = width;
    g_height = height;


	gcValues.function = GXcopy;
	gcValuesMask = GCFunction;


	// Creating a graphics context
	img_ctx->gc = XCreateGC( img_ctx->display, img_ctx->window, gcValuesMask, &gcValues );
	XGetWindowAttributes( img_ctx->display, img_ctx->window, &windowAttributes );

	img_ctx->visual = windowAttributes.visual;
	img_ctx->depth = windowAttributes.depth;

	if( XShmQueryExtension( img_ctx->display ) )
        img_ctx->isShared = 1;
	else
	{
		img_ctx->isShared = 0;
		printf("Error. isShared = FALSE\n");
	}

	errno = 0;
	img_ctx->xImage = NULL;
	img_ctx->sharedPixmap = None;

	img_ctx->shmInfo.shmid = -1;
	img_ctx->shmInfo.shmaddr = NULL;


	if( ( img_ctx->xImage = XShmCreateImage( img_ctx->display, img_ctx->visual,
		img_ctx->depth, ZPixmap, NULL, &( img_ctx->shmInfo ), g_width, g_height ) ) == NULL )
	{
	    printf("Error. Failed to create image.\n");
		return -1;
	}

	if( ( img_ctx->shmInfo.shmid = shmget( IPC_PRIVATE,
		img_ctx->xImage->bytes_per_line * img_ctx->xImage->height,
		IPC_CREAT | 0777 ) ) < 0 )
	{
	    printf("Error. Failed to create a segment.\n");
		return -1;
	}

	if( ( img_ctx->shmInfo.shmaddr = (char *) shmat(img_ctx->shmInfo.shmid, 0, 0 ) ) < 0 )
	{
		img_ctx->shmInfo.shmaddr = NULL;
		return -1;
	}

	img_ctx->xImage->data = img_ctx->shmInfo.shmaddr;
	img_ctx->shmInfo.readOnly = false;
	if ( !XShmAttach( img_ctx->display, &( img_ctx->shmInfo ) ) )
	{
        printf("Error. Attach failed.\n");
		return -1;
	}

	return 0;
}
Exemple #29
0
int fbx_init(fbx_struct *fb, fbx_wh wh, int width_, int height_, int useShm)
{
	int width, height;
	int rmask, gmask, bmask, ps, i;
	#ifdef _WIN32
	BMINFO bminfo;  HBITMAP hmembmp=0;  RECT rect;  HDC hdc=NULL;
	#else
	XWindowAttributes xwa;  int shmok=1, alphaFirst, pixmap=0;
	#endif

	if(!fb) _throw("Invalid argument");

	#ifdef _WIN32

	if(!wh) _throw("Invalid argument");
	_w32(GetClientRect(wh, &rect));
	if(width_>0) width=width_;
	else
	{
		width=rect.right-rect.left;  if(width<=0) width=MINWIDTH;
	}
	if(height_>0) height=height_;
	else
	{
		height=rect.bottom-rect.top;  if(height<=0) height=MINHEIGHT;
	}
	if(fb->wh==wh)
	{
		if(width==fb->width && height==fb->height && fb->hmdc && fb->hdib
			&& fb->bits)
			return 0;
		else if(fbx_term(fb)==-1) return -1;
	}
	memset(fb, 0, sizeof(fbx_struct));
	fb->wh=wh;

	_w32(hdc=GetDC(fb->wh));
	_w32(fb->hmdc=CreateCompatibleDC(hdc));
	_w32(hmembmp=CreateCompatibleBitmap(hdc, width, height));
	_w32(GetDeviceCaps(hdc, RASTERCAPS)&RC_BITBLT);
	_w32(GetDeviceCaps(fb->hmdc, RASTERCAPS)&RC_DI_BITMAP);
	bminfo.bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
	bminfo.bmi.bmiHeader.biBitCount=0;
	_w32(GetDIBits(fb->hmdc, hmembmp, 0, 1, NULL, &bminfo.bmi, DIB_RGB_COLORS));
	_w32(GetDIBits(fb->hmdc, hmembmp, 0, 1, NULL, &bminfo.bmi, DIB_RGB_COLORS));
	_w32(DeleteObject(hmembmp));  hmembmp=0;
		/* (we only needed it to get the screen properties) */
	ps=bminfo.bmi.bmiHeader.biBitCount/8;
	if(width>0) bminfo.bmi.bmiHeader.biWidth=width;
	if(height>0) bminfo.bmi.bmiHeader.biHeight=height;
	fb->width=bminfo.bmi.bmiHeader.biWidth;
	fb->height=bminfo.bmi.bmiHeader.biHeight;

	if(ps<3)
	{
		/* Make the buffer BGRA */
		bminfo.bmi.bmiHeader.biCompression=BI_BITFIELDS;
		bminfo.bmi.bmiHeader.biBitCount=32;
		ps=4;
		(*(DWORD *)&bminfo.bmi.bmiColors[0])=0xFF0000;
		(*(DWORD *)&bminfo.bmi.bmiColors[1])=0xFF00;
		(*(DWORD *)&bminfo.bmi.bmiColors[2])=0xFF;
	}

	fb->pitch=BMPPAD(fb->width*ps);  /* Windoze bitmaps are always padded */

	if(bminfo.bmi.bmiHeader.biCompression==BI_BITFIELDS)
	{
		rmask=(*(DWORD *)&bminfo.bmi.bmiColors[0]);
		gmask=(*(DWORD *)&bminfo.bmi.bmiColors[1]);
		bmask=(*(DWORD *)&bminfo.bmi.bmiColors[2]);
	}
	else
	{
		rmask=0xFF0000;
		gmask=0xFF00;
		bmask=0xFF;
	}

	fb->format=-1;
	for(i=0; i<FBX_FORMATS; i++)
		if(rmask==fbx_rmask[i] && gmask==fbx_gmask[i] && bmask==fbx_bmask[i]
			&& ps==fbx_ps[i] && fbx_alphafirst[i]==0) fb->format=i;
	if(fb->format==-1) _throw("Display has unsupported pixel format");

	bminfo.bmi.bmiHeader.biHeight=-bminfo.bmi.bmiHeader.biHeight;
		/* (our convention is top-down) */
	_w32(fb->hdib=CreateDIBSection(hdc, &bminfo.bmi, DIB_RGB_COLORS,
		(void **)&fb->bits, NULL, 0));
	_w32(SelectObject(fb->hmdc, fb->hdib));
	ReleaseDC(fb->wh, hdc);
	return 0;

	finally:
	if(hmembmp) DeleteObject(hmembmp);
	if(hdc) ReleaseDC(fb->wh, hdc);

	#else

	if(!wh.dpy || !wh.d) _throw("Invalid argument");
	if(wh.v)
	{
		_x11(XGetGeometry(wh.dpy, wh.d, &xwa.root, &xwa.x, &xwa.y,
			(unsigned int *)&xwa.width, (unsigned int *)&xwa.height,
			(unsigned int *)&xwa.border_width, (unsigned int *)&xwa.depth));
		xwa.visual=wh.v;
		useShm=0;
		pixmap=1;
	}
	else
	{
		_x11(XGetWindowAttributes(wh.dpy, wh.d, &xwa));
	}
	if(width_>0) width=width_;  else width=xwa.width;
	if(height_>0) height=height_;  else height=xwa.height;
	if(fb->wh.dpy==wh.dpy && fb->wh.d==wh.d)
	{
		if(width==fb->width && height==fb->height && fb->xi && fb->xgc && fb->bits)
			return 0;
		else if(fbx_term(fb)==-1) return -1;
	}
	memset(fb, 0, sizeof(fbx_struct));
	fb->wh.dpy=wh.dpy;  fb->wh.d=wh.d;

	#ifdef USESHM
	if(!useShm)
	{
		static int alreadyWarned=0;
		if(!alreadyWarned && warningFile)
		{
			fprintf(warningFile, "[FBX] Disabling shared memory blitting\n");
			alreadyWarned=1;
		}
	}
	if(useShm && XShmQueryExtension(fb->wh.dpy))
	{
		static int alreadyWarned=0;
		fb->shminfo.shmid=-1;
		if(!(fb->xi=XShmCreateImage(fb->wh.dpy, xwa.visual, xwa.depth,
			ZPixmap, NULL, &fb->shminfo, width, height)))
		{
			useShm=0;  goto noshm;
		}
		if((fb->shminfo.shmid=shmget(IPC_PRIVATE,
			fb->xi->bytes_per_line*fb->xi->height+1, IPC_CREAT|0777))==-1)
		{
			useShm=0;  XDestroyImage(fb->xi);  goto noshm;
		}
		if((fb->shminfo.shmaddr=fb->xi->data
			=(char *)shmat(fb->shminfo.shmid, 0, 0))==(char *)-1)
		{
			useShm=0;  XDestroyImage(fb->xi);
			shmctl(fb->shminfo.shmid, IPC_RMID, 0);  goto noshm;
		}
		fb->shminfo.readOnly=False;
		XLockDisplay(fb->wh.dpy);
		XSync(fb->wh.dpy, False);
		prevHandler=XSetErrorHandler(xhandler);
		extok=1;
		serial=NextRequest(fb->wh.dpy);
		XShmAttach(fb->wh.dpy, &fb->shminfo);
		XSync(fb->wh.dpy, False);
		XSetErrorHandler(prevHandler);
		shmok=extok;
		if(!alreadyWarned && !shmok && warningFile)
		{
			fprintf(warningFile,
				"[FBX] WARNING: MIT-SHM extension failed to initialize (this is normal on a\n");
			fprintf(warningFile,
				"[FBX]    remote connection.)  Will use X Pixmap drawing instead.\n");
			alreadyWarned=1;
		}
		XUnlockDisplay(fb->wh.dpy);
		if(shmok)
		{
			char *env=getenv("FBX_USESHMPIXMAPS");
			if(env && !strcmp(env, "1"))
			{
				static int alreadyWarned=0;
				if(!alreadyWarned && warningFile)
				{
					fprintf(warningFile, "[FBX] Using MIT-SHM pixmaps\n");
					alreadyWarned=1;
				}
				fb->pm=XShmCreatePixmap(fb->wh.dpy, fb->wh.d, fb->shminfo.shmaddr,
					&fb->shminfo, width, height, xwa.depth);
				if(!fb->pm) shmok=0;
			}
		}
		shmctl(fb->shminfo.shmid, IPC_RMID, 0);
		if(!shmok)
		{
			useShm=0;  XDestroyImage(fb->xi);  shmdt(fb->shminfo.shmaddr);
			shmctl(fb->shminfo.shmid, IPC_RMID, 0);  goto noshm;
		}
		fb->xattach=1;  fb->shm=1;
	}
	else if(useShm)
	{
		static int alreadyWarned=0;
		if(!alreadyWarned && warningFile)
		{
			fprintf(warningFile,
				"[FBX] WARNING: MIT-SHM extension not available.  Will use X pixmap\n");
			fprintf(warningFile, "[FBX]    drawing instead.\n");
			alreadyWarned=1;
		}
		useShm=0;
	}
	noshm:
	if(!useShm)
	#endif
	{
		if(!pixmap)
			_x11(fb->pm=XCreatePixmap(fb->wh.dpy, fb->wh.d, width, height,
				xwa.depth));
		_x11(fb->xi=XCreateImage(fb->wh.dpy, xwa.visual, xwa.depth, ZPixmap, 0,
			NULL, width, height, 8, 0));
		if((fb->xi->data=(char *)malloc(fb->xi->bytes_per_line*fb->xi->height+1))
			==NULL)
			_throw("Memory allocation error");
	}
	ps=fb->xi->bits_per_pixel/8;
	fb->width=fb->xi->width;
	fb->height=fb->xi->height;
	fb->pitch=fb->xi->bytes_per_line;
	if(fb->width!=width || fb->height!=height)
		_throw("Bitmap returned does not match requested size");
	rmask=fb->xi->red_mask;  gmask=fb->xi->green_mask;  bmask=fb->xi->blue_mask;
	alphaFirst=0;
	if(fb->xi->byte_order==MSBFirst)
	{
		if(ps<4)
		{
			rmask=fb->xi->blue_mask;  gmask=fb->xi->green_mask;
			bmask=fb->xi->red_mask;
		}
		else alphaFirst=1;
	}

	fb->format=-1;
	for(i=0; i<FBX_FORMATS; i++)
		if(rmask==fbx_rmask[i] && gmask==fbx_gmask[i] && bmask==fbx_bmask[i]
			&& ps==fbx_ps[i] && fbx_alphafirst[i]==alphaFirst) fb->format=i;
	if(fb->format==-1) _throw("Display has unsupported pixel format");

	fb->bits=fb->xi->data;
	fb->pixmap=pixmap;
	_x11(fb->xgc=XCreateGC(fb->wh.dpy, fb->pm? fb->pm:fb->wh.d, 0, NULL));
	return 0;

	finally:

	#endif

	fbx_term(fb);
	return -1;
}
Exemple #30
0
int xf_xshm_init(xfInfo* xfi)
{
	Bool pixmaps;
	int major, minor;

	if (XShmQueryExtension(xfi->display) != False)
	{
		XShmQueryVersion(xfi->display, &major, &minor, &pixmaps);

		if (pixmaps != True)
		{
			fprintf(stderr, "XShmQueryVersion failed\n");
			return -1;
		}
	}
	else
	{
		fprintf(stderr, "XShmQueryExtension failed\n");
		return -1;
	}

	xfi->fb_shm_info.shmid = -1;
	xfi->fb_shm_info.shmaddr = (char*) -1;

	xfi->fb_image = XShmCreateImage(xfi->display, xfi->visual, xfi->depth,
			ZPixmap, NULL, &(xfi->fb_shm_info), xfi->width, xfi->height);

	if (!xfi->fb_image)
	{
		fprintf(stderr, "XShmCreateImage failed\n");
		return -1;
	}

	xfi->fb_shm_info.shmid = shmget(IPC_PRIVATE,
			xfi->fb_image->bytes_per_line * xfi->fb_image->height, IPC_CREAT | 0600);

	if (xfi->fb_shm_info.shmid == -1)
	{
		fprintf(stderr, "shmget failed\n");
		return -1;
	}

	xfi->fb_shm_info.readOnly = False;
	xfi->fb_shm_info.shmaddr = shmat(xfi->fb_shm_info.shmid, 0, 0);
	xfi->fb_image->data = xfi->fb_shm_info.shmaddr;

	if (xfi->fb_shm_info.shmaddr == ((char*) -1))
	{
		fprintf(stderr, "shmat failed\n");
		return -1;
	}

	XShmAttach(xfi->display, &(xfi->fb_shm_info));
	XSync(xfi->display, False);

	shmctl(xfi->fb_shm_info.shmid, IPC_RMID, 0);

	fprintf(stderr, "display: %p root_window: %p width: %d height: %d depth: %d\n",
			xfi->display, (void*) xfi->root_window, xfi->fb_image->width, xfi->fb_image->height, xfi->fb_image->depth);

	xfi->fb_pixmap = XShmCreatePixmap(xfi->display,
			xfi->root_window, xfi->fb_image->data, &(xfi->fb_shm_info),
			xfi->fb_image->width, xfi->fb_image->height, xfi->fb_image->depth);

	return 0;
}