/* ** mlx_new_image.c for MiniLibX in raytraceur ** ** Made by Charlie Root ** Login ** ** Started on Mon Aug 14 15:29:14 2000 Charlie Root ** Last update Wed May 25 16:46:31 2011 Olivier Crouzet */ #include "mlx_int.h" /* ** To handle X errors */ #define X_ShmAttach 1 int mlx_X_error; int shm_att_pb(Display *d,XErrorEvent *ev) { if (ev->request_code==146 && ev->minor_code==X_ShmAttach) write(2,WARN_SHM_ATTACH,strlen(WARN_SHM_ATTACH)); mlx_X_error = 1; } /* ** Data malloc : width+32 ( bitmap_pad=32 ), *4 = *32 / 8bit */ 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); } void *mlx_int_new_image(t_xvar *xvar,int width, int height,int format) { t_img *img; if (!(img = malloc(sizeof(*img))) || !(img->data = malloc((width+32)*height*4))) return ((void *)0); bzero(img->data,(width+32)*height*4); img->image = XCreateImage(xvar->display,xvar->visual,xvar->depth,format,0, img->data,width,height,32,0); if (!img->image) { free(img->data); free(img); return ((void *)0); } img->gc = 0; img->size_line = img->image->bytes_per_line; img->bpp = img->image->bits_per_pixel; img->width = width; img->height = height; img->pix = XCreatePixmap(xvar->display,xvar->root,width,height,xvar->depth); img->format = format; img->type = MLX_TYPE_XIMAGE; if (xvar->do_flush) XFlush(xvar->display); return (img); } void *mlx_new_image(t_xvar *xvar,int width, int height) { t_img *img; if (xvar->use_xshm) if (img = mlx_int_new_xshm_image(xvar,width,height,ZPixmap)) return (img); return (mlx_int_new_image(xvar,width,height,ZPixmap)); } void *mlx_new_image2(t_xvar *xvar,int width, int height) { t_img *img; if (xvar->use_xshm) if (img = mlx_int_new_xshm_image(xvar,width,height,XYPixmap)) return (img); return (mlx_int_new_image(xvar,width,height,XYPixmap)); }