/ minilibx-linux / mlx_new_image.c
mlx_new_image.c
  1  /*
  2  ** mlx_new_image.c for MiniLibX in raytraceur
  3  ** 
  4  ** Made by Charlie Root
  5  ** Login   <ol@epitech.net>
  6  ** 
  7  ** Started on  Mon Aug 14 15:29:14 2000 Charlie Root
  8  ** Last update Wed May 25 16:46:31 2011 Olivier Crouzet
  9  */
 10  
 11  
 12  
 13  
 14  #include	"mlx_int.h"
 15  
 16  /*
 17  ** To handle X errors
 18  */
 19  
 20  #define	X_ShmAttach	1
 21  
 22  int	mlx_X_error;
 23  
 24  int	shm_att_pb(Display *d,XErrorEvent *ev)
 25  {
 26    if (ev->request_code==146 && ev->minor_code==X_ShmAttach)
 27      write(2,WARN_SHM_ATTACH,strlen(WARN_SHM_ATTACH));
 28    mlx_X_error = 1;
 29  }
 30  
 31  
 32  /*
 33  **  Data malloc :  width+32 ( bitmap_pad=32 ),    *4 = *32 / 8bit
 34  */
 35  
 36  
 37  void	*mlx_int_new_xshm_image(t_xvar *xvar,int width,int height,int format)
 38  {
 39    t_img	*img;
 40    int	(*save_handler)();
 41  
 42    if (!(img = malloc(sizeof(*img))))
 43      return ((void *)0);
 44    bzero(img,sizeof(*img));
 45    img->data = 0;
 46    img->image = XShmCreateImage(xvar->display,xvar->visual,xvar->depth,
 47  			       format,img->data,&(img->shm),width,height);
 48    if (!img->image)
 49      {
 50        free(img);
 51        return ((void *)0);
 52      }
 53    img->width = width;
 54    img->height = height;
 55    img->size_line = img->image->bytes_per_line;
 56    img->bpp = img->image->bits_per_pixel;
 57    img->format = format;
 58    img->shm.shmid = shmget(IPC_PRIVATE,(width+32)*height*4,IPC_CREAT|0777);
 59    if (img->shm.shmid==-1)
 60      {
 61        XDestroyImage(img->image);
 62        free(img);
 63        return ((void *)0);
 64      }
 65    img->data = img->shm.shmaddr = img->image->data = shmat(img->shm.shmid,0,0);
 66    if (img->data==(void *)-1)
 67      {
 68        shmctl(img->shm.shmid,IPC_RMID,0);
 69        XDestroyImage(img->image);
 70        free(img);
 71        return ((void *)0);
 72      }
 73    img->shm.readOnly = False;
 74    mlx_X_error = 0;
 75    save_handler = XSetErrorHandler(shm_att_pb);
 76    if (!XShmAttach(xvar->display,&(img->shm)) ||
 77        0&XSync(xvar->display,False) || mlx_X_error)
 78      {
 79        XSetErrorHandler(save_handler);
 80        shmdt(img->data);
 81        shmctl(img->shm.shmid,IPC_RMID,0);
 82        XDestroyImage(img->image);
 83        free(img);
 84        return ((void *)0);
 85      }
 86    XSetErrorHandler(save_handler);
 87    shmctl(img->shm.shmid,IPC_RMID,0);
 88    if (xvar->pshm_format==format)
 89      {
 90        img->pix = XShmCreatePixmap(xvar->display,xvar->root,img->shm.shmaddr,
 91  				  &(img->shm),width,height,xvar->depth);
 92        img->type = MLX_TYPE_SHM_PIXMAP;
 93      }
 94    else
 95      {
 96        img->pix = XCreatePixmap(xvar->display,xvar->root,
 97  			       width,height,xvar->depth);
 98        img->type = MLX_TYPE_SHM;
 99      }
100    if (xvar->do_flush)
101      XFlush(xvar->display);
102    return (img);
103  }
104  
105  
106  
107  void	*mlx_int_new_image(t_xvar *xvar,int width, int height,int format)
108  {
109    t_img	*img;
110  
111    if (!(img = malloc(sizeof(*img))))
112      return ((void *)0);
113    if (!(img->data = malloc((width+32)*height*4)))
114    {
115      free(img);
116      return ((void *)0);
117    }
118    bzero(img->data,(width+32)*height*4);
119    img->image = XCreateImage(xvar->display,xvar->visual,xvar->depth,format,0,
120  			    img->data,width,height,32,0);
121    if (!img->image)
122      {
123        free(img->data);
124        free(img);
125        return ((void *)0);
126      }
127    img->gc = 0;
128    img->size_line = img->image->bytes_per_line;
129    img->bpp = img->image->bits_per_pixel;
130    img->width = width;
131    img->height = height;
132    img->pix = XCreatePixmap(xvar->display,xvar->root,width,height,xvar->depth);
133    img->format = format;
134    img->type = MLX_TYPE_XIMAGE;
135    if (xvar->do_flush)
136      XFlush(xvar->display);
137    return (img);
138  }
139  
140  
141  void	*mlx_new_image(t_xvar *xvar,int width, int height)
142  {
143    t_img	*img;
144  
145    if (xvar->use_xshm)
146      if (img = mlx_int_new_xshm_image(xvar,width,height,ZPixmap))
147        return (img);
148    return (mlx_int_new_image(xvar,width,height,ZPixmap));
149  }
150  
151  void	*mlx_new_image2(t_xvar *xvar,int width, int height)
152  {
153    t_img	*img;
154  
155    if (xvar->use_xshm)
156      if (img = mlx_int_new_xshm_image(xvar,width,height,XYPixmap))
157        return (img);
158    return (mlx_int_new_image(xvar,width,height,XYPixmap));
159  }