1 /*
2  * Copyright © 2007 Bart Massey <bart@cs.pdx.edu>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
18  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20  *
21  * Except as contained in this notice, the names of the authors or their
22  * institutions shall not be used in advertising or otherwise to promote the
23  * sale, use or other dealings in this Software without prior written
24  * authorization from the authors.
25  */
26 
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30 
31 #include <stdlib.h>
32 #include <stdio.h>
33 
34 #include <sys/ipc.h>
35 #include <sys/shm.h>
36 
37 #include <xcb/xcb.h>
38 #include <xcb/shm.h>
39 
40 #include <xcb/xcb_aux.h>
41 #include "xcb_image.h"
42 
43 #define W_W 40
44 #define W_H 40
45 
46 
47 
48 int
main(int argc,char * argv[])49 main (int argc, char *argv[])
50 {
51   xcb_connection_t   *c;
52   xcb_screen_t       *screen;
53   xcb_drawable_t      win;
54   xcb_drawable_t      rect;
55   xcb_rectangle_t     rect_coord = { 0, 0, W_W, W_H};
56   xcb_gcontext_t      bgcolor, fgcolor;
57   xcb_point_t         points[2];
58   uint32_t           mask;
59   uint32_t           valgc[2];
60   uint32_t           valwin[3];
61   int              depth;
62   int              screen_nbr;
63   xcb_generic_event_t *e;
64   uint8_t format;
65   xcb_image_t *img;
66   xcb_shm_query_version_reply_t *rep;
67   xcb_shm_segment_info_t shminfo;
68 
69   /* Open the connexion to the X server and get the first screen */
70   c = xcb_connect (NULL, &screen_nbr);
71   screen = xcb_aux_get_screen (c, screen_nbr);
72   depth = xcb_aux_get_depth (c, screen);
73 
74   /* Create a black graphic context for drawing in the foreground */
75   win = screen->root;
76 
77   fgcolor = xcb_generate_id(c);
78   mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
79   valgc[0] = screen->black_pixel;
80   valgc[1] = 0; /* no graphics exposures */
81   xcb_create_gc(c, fgcolor, win, mask, valgc);
82 
83   bgcolor = xcb_generate_id(c);
84   mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
85   valgc[0] = screen->white_pixel;
86   valgc[1] = 0; /* no graphics exposures */
87   xcb_create_gc(c, bgcolor, win, mask, valgc);
88 
89   /* Shm test */
90   printf ("shm test begin\n");
91   rep = xcb_shm_query_version_reply (c,
92 				 xcb_shm_query_version (c),
93 				 NULL);
94   if (!rep || !rep->shared_pixmaps ||
95       rep->major_version < 1 ||
96       (rep->major_version == 1 && rep->minor_version == 0))
97       {
98 	  printf ("No or insufficient shm support...\n");
99 	  exit (0);
100       }
101   format = rep->pixmap_format;
102   img = xcb_image_create_native (c, W_W, W_H, format, depth,
103 				     0, ~0, 0);
104 
105   if (!img)
106       {
107 	  printf ("Can't create image...\n");
108 	  exit (0);
109       }
110 
111   printf ("Create image summary:\n");
112   printf (" * format..........: %d\n", img->format);
113   printf (" * byte order......: %d\n", img->byte_order);
114   printf (" * bitmap unit.....: %d\n", img->bpp);
115   printf (" * bitmap order....: %d\n", img->bit_order);
116   printf (" * bitmap pad......: %d\n", img->scanline_pad);
117 
118   shminfo.shmid = shmget (IPC_PRIVATE, img->size, IPC_CREAT|0777);
119   shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
120   img->data = shminfo.shmaddr;
121 
122   shminfo.shmseg = xcb_generate_id (c);
123   xcb_shm_attach(c, shminfo.shmseg, shminfo.shmid, 0);
124   shmctl(shminfo.shmid, IPC_RMID, 0);
125 
126   /* Draw in the image */
127   printf ("put the pixel\n");
128   xcb_image_put_pixel (img, 20, 20, 65535);
129   printf ("fin put pixel\n");
130 
131   /* Ask for our window's Id */
132   win = xcb_generate_id(c);
133 
134   /* Create the window */
135   mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE;
136   valwin[0] = screen->white_pixel;
137   valwin[1] = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE;
138   valwin[2] = XCB_EVENT_MASK_BUTTON_PRESS;
139   xcb_create_window (c,                        /* Connection          */
140  		   0,                        /* depth               */
141 		   win,                      /* window Id           */
142 		   screen->root,             /* parent window       */
143 		   0, 0,                     /* x, y                */
144 		   W_W, W_H,                 /* width, height       */
145 		   10,                       /* border_width        */
146 		   XCB_WINDOW_CLASS_INPUT_OUTPUT,/* class               */
147 		   screen->root_visual,      /* visual              */
148 		   mask, valwin);            /* masks, not used yet */
149 
150   /* Map the window on the screen */
151   xcb_map_window (c, win);
152 
153   /* Create a Pixmap that will fill the window */
154   rect = xcb_generate_id (c);
155   xcb_create_pixmap(c, depth, rect, win, W_W, W_H);
156   xcb_poly_fill_rectangle(c, rect, bgcolor, 1, &rect_coord);
157   points[0].x = 0;
158   points[0].y = 0;
159   points[1].x = 1;
160   points[1].y = 1;
161   xcb_poly_line(c, XCB_COORD_MODE_ORIGIN, rect, fgcolor, 2, points);
162 
163   xcb_flush (c);
164 
165   while ((e = xcb_wait_for_event(c)))
166     {
167       switch (e->response_type)
168 	{
169 	case XCB_EXPOSE:
170 	  {
171 	    xcb_copy_area(c, rect, win, bgcolor,
172 			0, 0, 0, 0, W_W, W_H);
173 	    printf ("put image\n");
174 	    xcb_image_shm_put (c, win, fgcolor,
175 			       img, shminfo,
176 			       0, 0, 0, 0, W_W,W_H,
177 			       0);
178 	    xcb_flush (c);
179 	    break;
180 	  }
181 	}
182       free (e);
183     }
184 
185   return 1;
186 }
187