├── README.md ├── X11 └── Xlib.h ├── XLib.c ├── example.c └── m.sh /README.md: -------------------------------------------------------------------------------- 1 | # picox 2 | A minimal X11/Xlib client library 3 | (currently under construction) -------------------------------------------------------------------------------- /X11/Xlib.h: -------------------------------------------------------------------------------- 1 | /* X.h */ 2 | 3 | #define X_PROTOCOL 11 /* current protocol version */ 4 | #define X_PROTOCOL_REVISION 0 /* current minor version */ 5 | 6 | typedef unsigned long XID; 7 | typedef XID Window; 8 | typedef XID Font; 9 | typedef XID Pixmap; 10 | typedef XID Colormap; 11 | typedef XID GContext; 12 | typedef XID Drawable; 13 | 14 | typedef unsigned long VisualID; 15 | 16 | 17 | #define CopyFromParent 0 18 | 19 | 20 | #define ExposureMask (1L<<15) 21 | #define KeyPressMask (1L<<0) 22 | 23 | #define KeyPress 2 24 | #define Expose 12 25 | 26 | #define CWBackPixel (1L<<1) 27 | #define CWBorderPixel (1L<<3) 28 | #define CWEventMask (1L<<11) 29 | 30 | #define GCFunction (1L<<0) 31 | #define GCPlaneMask (1L<<1) 32 | #define GCForeground (1L<<2) 33 | #define GCBackground (1L<<3) 34 | #define GCLineWidth (1L<<4) 35 | #define GCLineStyle (1L<<5) 36 | #define GCCapStyle (1L<<6) 37 | #define GCJoinStyle (1L<<7) 38 | #define GCFillStyle (1L<<8) 39 | #define GCFillRule (1L<<9) 40 | #define GCTile (1L<<10) 41 | #define GCStipple (1L<<11) 42 | #define GCTileStipXOrigin (1L<<12) 43 | #define GCTileStipYOrigin (1L<<13) 44 | #define GCFont (1L<<14) 45 | #define GCSubwindowMode (1L<<15) 46 | #define GCGraphicsExposures (1L<<16) 47 | #define GCClipXOrigin (1L<<17) 48 | #define GCClipYOrigin (1L<<18) 49 | #define GCClipMask (1L<<19) 50 | #define GCDashOffset (1L<<20) 51 | #define GCDashList (1L<<21) 52 | #define GCArcMode (1L<<22) 53 | 54 | #define GXcopy 0x3 /* src */ 55 | 56 | #define CapButt 1 57 | #define ArcPieSlice 1 /* join endpoints to center of arc */ 58 | 59 | 60 | /* Xlib.h */ 61 | 62 | #define Bool int 63 | 64 | #define RootWindow(dpy, scr) (((dpy)->screens[(scr)]).root) 65 | #define DefaultScreen(dpy) ((dpy)->default_screen) 66 | #define DefaultGC(dpy, scr) (((dpy)->screens[(scr)]).default_gc) 67 | #define BlackPixel(dpy, scr) (((dpy)->screens[(scr)]).black_pixel) 68 | #define WhitePixel(dpy, scr) (((dpy)->screens[(scr)]).white_pixel) 69 | #define AllPlanes (~0) 70 | 71 | typedef struct _XExtData 72 | { 73 | int number; /* number returned by XRegisterExtension */ 74 | struct _XExtData *next; /* next item on list of data for structure */ 75 | int (*free_private)(); /* called to free private storage */ 76 | char *private_data; /* data private to this extension. */ 77 | } XExtData; 78 | 79 | typedef struct 80 | { 81 | int function; /* logical operation */ 82 | unsigned long plane_mask; /* plane mask */ 83 | unsigned long foreground; /* foreground pixel */ 84 | unsigned long background; /* background pixel */ 85 | int line_width; /* line width */ 86 | int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */ 87 | int cap_style; /* CapNotLast, CapButt, CapRound, CapProjecting */ 88 | int join_style; /* JoinMiter, JoinRound, JoinBevel */ 89 | int fill_style; /* FillSolid, FillTiled, FillStippled, FillOpaeueStippled */ 90 | int fill_rule; /* EvenOddRule, WindingRule */ 91 | int arc_mode; /* ArcChord, ArcPieSlice */ 92 | Pixmap tile; /* tile pixmap for tiling operations */ 93 | Pixmap stipple; /* stipple 1 plane pixmap for stipping */ 94 | int ts_x_origin; /* offset for tile or stipple operations */ 95 | int ts_y_origin; 96 | Font font; /* default text font for text operations */ 97 | int subwindow_mode; /* ClipByChildren, IncludeInferiors */ 98 | Bool graphics_exposures; /* boolean, should exposures be generated */ 99 | int clip_x_origin; /* origin for clipping */ 100 | int clip_y_origin; 101 | Pixmap clip_mask; /* bitmap clipping; other calls for rects */ 102 | int dash_offset; /* patterned/dashed line information */ 103 | char dashes; 104 | } XGCValues; 105 | 106 | typedef struct _XGC 107 | { 108 | XExtData *ext_data; /* hook for extension to hang data */ 109 | GContext gid; /* protocol ID for graphics context */ 110 | Bool rects; /* boolean: TRUE if clipmask is list of rectangles */ 111 | Bool dashes; /* boolean: TRUE if dash-list is really a list */ 112 | unsigned long dirty; /* cache dirty bits */ 113 | XGCValues values; /* shadow structure of values */ 114 | } *GC; 115 | 116 | typedef struct 117 | { 118 | XExtData *ext_data; /* hook for extension to hang data */ 119 | VisualID visualid; /* visual id of this visual */ 120 | int class; /* class of screen (monochrome, etc.) */ 121 | unsigned long red_mask, green_mask, blue_mask; /* mask values */ 122 | int bits_per_rgb; /* log base 2 of distinct color values */ 123 | int map_entries; /* color map entries */ 124 | } Visual; 125 | 126 | typedef struct 127 | { 128 | int depth; /* this depth (Z) of the depth */ 129 | int nvisuals; /* number of Visual types at this depth */ 130 | Visual *visuals; /* list of visuals possible at this depth */ 131 | } Depth; 132 | 133 | typedef struct 134 | { 135 | struct _XDisplay *display; /* back pointer to display structure */ 136 | Window root; /* Root window id. */ 137 | int width, height; /* width and height of screen */ 138 | int mwidth, mheight; /* width and height of in millimeters */ 139 | int ndepths; /* number of depths possible */ 140 | Depth *depths; /* list of allowable depths on the screen */ 141 | int root_depth; /* bits per pixel */ 142 | Visual *root_visual; /* root visual */ 143 | GC default_gc; /* GC for the root root visual */ 144 | Colormap cmap; /* default color map */ 145 | unsigned long white_pixel; 146 | unsigned long black_pixel; /* White and Black pixel values */ 147 | int max_maps, min_maps; /* max and min color maps */ 148 | int backing_store; /* Never, WhenMapped, Always */ 149 | Bool save_unders; 150 | long root_input_mask; /* initial root input mask */ 151 | 152 | } Screen; 153 | 154 | typedef struct 155 | { 156 | // XExtData *ext_data; /* hook for extension to hang data */ 157 | void *ext_data; /* hook for extension to hang data */ 158 | int depth; /* depth of this image format */ 159 | int bits_per_pixel; /* bits/pixel at this depth */ 160 | int scanline_pad; /* scanline must padded to this multiple */ 161 | } ScreenFormat; 162 | 163 | typedef struct _XDisplay 164 | { 165 | int fd; /* Network socket. */ 166 | 167 | int proto_major_version; /* maj. version of server's X protocol */ 168 | int proto_minor_version; /* minor version of servers X protocol */ 169 | char *vendor; /* vendor of the server hardware */ 170 | 171 | long resource_base; /* resource ID base */ 172 | long resource_mask; /* resource ID mask bits */ 173 | long resource_id; /* allocator current ID */ 174 | int resource_shift; /* allocator shift to correct bits */ 175 | 176 | int byte_order; /* screen byte order, LSBFirst, MSBFirst */ 177 | int bitmap_unit; /* padding and data requirements */ 178 | int bitmap_pad; /* padding requirements on bitmaps */ 179 | int bitmap_bit_order; /* LeastSignificant or MostSignificant */ 180 | int nformats; /* number of pixmap formats in list */ 181 | ScreenFormat *pixmap_format; /* pixmap format list */ 182 | 183 | int release; /* release of the server */ 184 | 185 | int request; /* sequence number of last request. */ 186 | char *buffer; /* Output buffer starting address. */ 187 | char *bufptr; /* Output buffer index pointer. */ 188 | char *bufmax; /* Output buffer maximum+1 address. */ 189 | unsigned max_request_size; /* maximum number 32 bit words in request*/ 190 | 191 | int default_screen; /* default screen for operations */ 192 | int nscreens; /* number of screens on this server*/ 193 | Screen *screens; /* pointer to list of screens */ 194 | 195 | int motion_buffer; /* size of motion buffer */ 196 | 197 | int min_keycode; /* minimum defined keycode */ 198 | int max_keycode; /* maximum defined keycode */ 199 | 200 | // int (*event_vec[128])();/* vector for wire to event */ 201 | // int (*wire_vec[128])(); /* vector for event to wire */ 202 | 203 | } Display; 204 | 205 | typedef struct _XEvent 206 | { 207 | unsigned char type; /* of event (KeyPressed, ExposeWindow, etc.) */ 208 | unsigned char detail; 209 | unsigned short sequence_number; 210 | unsigned long p1; 211 | unsigned long p2; 212 | unsigned long p3; 213 | unsigned long p4; 214 | unsigned long p5; 215 | unsigned long p6; 216 | unsigned long p7; 217 | } XEvent; 218 | 219 | XID XAllocID(Display *dpy); 220 | void XFlush(Display *d); 221 | Display *XOpenDisplay(char *d); 222 | GC XCreateGC(Display *dpy, Drawable d, unsigned long valuemask, XGCValues *values); 223 | void XChangeGC(Display *dpy, GC gc, unsigned long valuemask, XGCValues *values); 224 | GContext XGContextFromGC(GC gc); 225 | Window XCreateSimpleWindow(Display *d, Window p, int x, int y, int w, int h, int bw, unsigned long b, unsigned long bg); 226 | void XSelectInput(Display *d, Window w, unsigned long mask); 227 | void XMapWindow(Display *d, Window w); 228 | void XNextEvent(Display *d, XEvent *e); 229 | void XFillRectangle(Display *d, Window drw, GC gc, int x, int y, int w, int h); 230 | void XDrawString(Display *dpy, Drawable d, GC gc, int x, int y, char *string, int length); 231 | void XCloseDisplay(Display *d); 232 | 233 | /* end Xlib.h */ 234 | -------------------------------------------------------------------------------- /XLib.c: -------------------------------------------------------------------------------- 1 | /* Xlib.c */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #ifdef WIN32 14 | #include 15 | #else 16 | #include 17 | #endif 18 | 19 | /* Xproto.h */ 20 | 21 | #define X_TCP_PORT 6000 /* add display number */ 22 | typedef struct 23 | { 24 | unsigned char byteOrder; 25 | unsigned char pad; 26 | unsigned short majorVersion, minorVersion; 27 | unsigned short nbytesAuthProto; /* Authorization protocol */ 28 | unsigned short nbytesAuthString; /* Authorization string */ 29 | unsigned short pad2; 30 | } xConnClientPrefix; 31 | 32 | typedef struct 33 | { 34 | unsigned char success; 35 | unsigned char lengthReason; /*num bytes in string following if failure */ 36 | unsigned short majorVersion, minorVersion; 37 | unsigned short length; /* 1/4 additional bytes in setup info */ 38 | } xConnSetupPrefix; 39 | 40 | typedef struct 41 | { 42 | unsigned long release; 43 | unsigned long ridBase, ridMask; 44 | unsigned long motionBufferSize; 45 | unsigned short nbytesVendor; /* number of bytes in vendor string */ 46 | unsigned short maxRequestSize; 47 | unsigned char numRoots; /* number of roots structs to follow */ 48 | unsigned char numFormats; /* number of pixmap formats */ 49 | unsigned char imageByteOrder; /* LSBFirst, MSBFirst */ 50 | unsigned char bitmapBitOrder; /* LeastSignificant, MostSign...*/ 51 | unsigned char bitmapScanlineUnit; /* 8, 16, 32 */ 52 | unsigned char bitmapScanlinePad; /* 8, 16, 32 */ 53 | unsigned char minKeyCode, maxKeyCode; 54 | unsigned long pad2; 55 | } xConnSetup; 56 | 57 | typedef struct 58 | { 59 | unsigned char depth; 60 | unsigned char bitsPerPixel; 61 | unsigned char scanLinePad; 62 | unsigned char pad1; 63 | unsigned long pad2; 64 | } xPixmapFormat; 65 | 66 | typedef struct 67 | { 68 | unsigned char depth; 69 | unsigned char pad1; 70 | unsigned short nVisuals; /* number of xVisualType structures following */ 71 | unsigned long pad2; 72 | } xDepth; 73 | 74 | typedef struct 75 | { 76 | unsigned long visualID; 77 | unsigned char class; 78 | unsigned char bitsPerRGB; 79 | unsigned short colormapEntries; 80 | unsigned long redMask, greenMask, blueMask; 81 | unsigned long pad; 82 | } xVisualType; 83 | 84 | typedef struct 85 | { 86 | unsigned long windowId; 87 | unsigned long defaultColormap; 88 | unsigned long whitePixel, blackPixel; 89 | unsigned long currentInputMask; 90 | unsigned short pixWidth, pixHeight; 91 | unsigned short mmWidth, mmHeight; 92 | unsigned short minInstalledMaps, maxInstalledMaps; 93 | unsigned long rootVisualID; 94 | unsigned char backingStore; 95 | unsigned char saveUnders; 96 | unsigned char rootDepth; 97 | unsigned char nDepths; /* number of xDepth structures following */ 98 | } xWindowRoot; 99 | 100 | /* Requests */ 101 | typedef struct 102 | { 103 | unsigned char reqType; 104 | unsigned char data; 105 | unsigned short length; 106 | } xReq; 107 | 108 | typedef struct 109 | { 110 | unsigned char reqType; 111 | unsigned char pad; 112 | unsigned short length; 113 | unsigned long gc; 114 | unsigned long drawable; 115 | unsigned long mask; 116 | } xCreateGCReq; 117 | 118 | typedef struct { 119 | unsigned char reqType; 120 | unsigned char pad; 121 | unsigned short length; 122 | unsigned long gc; 123 | unsigned long mask; 124 | } xChangeGCReq; 125 | 126 | typedef struct 127 | { 128 | unsigned char reqType; 129 | unsigned char depth; 130 | unsigned short length; 131 | unsigned long wid, parent; 132 | short x, y; 133 | unsigned short width, height, borderWidth; 134 | unsigned short class; 135 | unsigned long visual; 136 | unsigned long mask; 137 | } xCreateWindowReq; 138 | 139 | typedef struct 140 | { 141 | unsigned char reqType; 142 | unsigned char pad; 143 | unsigned short length; 144 | unsigned long window; 145 | unsigned long valueMask; 146 | } xChangeWindowAttributesReq; 147 | 148 | typedef struct 149 | { 150 | unsigned char reqType; 151 | unsigned char pad; 152 | unsigned short length; 153 | unsigned long id; /* a Window, Drawable, Font, GContext, Pixmap, etc. */ 154 | } xResourceReq; 155 | 156 | typedef struct _xSegment 157 | { 158 | short x1, y1, x2, y2; 159 | } xSegment; 160 | 161 | typedef struct _xPoint 162 | { 163 | short x,y; 164 | } xPoint; 165 | 166 | typedef struct _xRectangle 167 | { 168 | short x, y; 169 | unsigned short width, height; 170 | } xRectangle; 171 | 172 | typedef struct 173 | { 174 | unsigned char reqType; 175 | unsigned char pad; 176 | unsigned short length; 177 | unsigned long drawable; 178 | unsigned long gc; 179 | } xPolySegmentReq; 180 | 181 | typedef xPolySegmentReq xPolyArcReq; 182 | typedef xPolySegmentReq xPolyRectangleReq; 183 | typedef xPolySegmentReq xPolyFillRectangleReq; 184 | typedef xPolySegmentReq xPolyFillArcReq; 185 | 186 | typedef struct { 187 | unsigned char reqType; 188 | unsigned char pad; 189 | unsigned short length; 190 | unsigned long drawable; 191 | unsigned long gc; 192 | short x, y; /* items (xTextElt) start after struct */ 193 | } xPolyTextReq; 194 | 195 | typedef xPolyTextReq xPolyText8Req; 196 | typedef xPolyTextReq xPolyText16Req; 197 | 198 | typedef struct { /* followed by string */ 199 | unsigned char len; /* number of *characters* in string, or FontChange (255) 200 | for font change, or 0 if just delta given */ 201 | char delta; 202 | } xTextElt; 203 | 204 | 205 | #define X_Error 0 /* Error */ 206 | 207 | /* Request codes */ 208 | #define X_CreateWindow 1 209 | #define X_ChangeWindowAttributes 2 210 | #define X_MapWindow 8 211 | #define X_CreateGC 55 212 | #define X_ChangeGC 56 213 | #define X_PolyFillRectangle 70 214 | #define X_PolyText8 74 215 | 216 | 217 | #define BUFSIZE 2048 /* X output buffer size. */ 218 | 219 | 220 | /* XLibInt.c */ 221 | 222 | XID XAllocID(Display *dpy) 223 | { 224 | unsigned long id; 225 | id = dpy->resource_base + (dpy->resource_id++ << dpy->resource_shift); 226 | printf("%ld=XallocID(resource_base = %ld dpy_resource_id = %ld resource_shift = %d)\n",id, 227 | dpy->resource_base, dpy->resource_id-1,dpy->resource_shift); 228 | return id; 229 | } 230 | 231 | /* XLib.c */ 232 | 233 | void XFlush(Display *d) 234 | { 235 | if (d->bufptr > d->buffer) 236 | { 237 | send(d->fd, d->buffer, d->bufptr - d->buffer, 0); 238 | d->bufptr = d->buffer; 239 | } 240 | } 241 | 242 | Display *XOpenDisplay(char *d) 243 | { 244 | static Screen scn; 245 | Display *dpy; 246 | char host[100]; 247 | int i = 0; 248 | int j,k; 249 | int display_num = 0; 250 | 251 | struct sockaddr_in inaddr; /* INET socket address. */ 252 | // struct sockaddr *addr; /* address to connect to */ 253 | struct hostent *host_ptr; 254 | int addrlen; /* length of address */ 255 | int fd; /* Network socket */ 256 | 257 | xConnClientPrefix client; /* client information */ 258 | xConnSetupPrefix prefix; /* prefix information */ 259 | int vendorlen; /* length of vendor string */ 260 | 261 | char *setup, *p; /* memory allocated at startup */ 262 | long setuplength; /* number of bytes in setup message */ 263 | int screen_num; /* screen number */ 264 | 265 | #ifdef WIN32 266 | WSADATA info; 267 | int rc; 268 | if ((rc = WSAStartup(MAKEWORD(2,0),&info)) != 0) 269 | { 270 | printf("WSAStartup failed with error %d\n",rc); 271 | WSACleanup(); 272 | return 0; 273 | } 274 | #endif 275 | 276 | if (d) 277 | { 278 | while (*d && *d != ':') host[i++] = *d++; 279 | if (*d) display_num = atoi(d + 1); 280 | } 281 | host[i] = '\0'; 282 | screen_num = 0; //?????after dot! 283 | 284 | if (!*host) gethostname(host, sizeof(host)); 285 | printf("host: %s\n", host); 286 | 287 | /* Get the statistics on the specified host. */ 288 | memset(&inaddr, 0, sizeof(struct sockaddr_in)); 289 | if ((inaddr.sin_addr.s_addr = inet_addr(host)) == -1) 290 | { 291 | if ((host_ptr = gethostbyname(host)) == NULL) 292 | { 293 | /* No such host! */ 294 | printf("no such host\n"); 295 | return 0; 296 | } 297 | 298 | /* Check the address type for an internet host. */ 299 | if (host_ptr->h_addrtype != AF_INET) 300 | { 301 | /* Not an Internet host! */ 302 | printf("not and internet host\n"); 303 | return 0; 304 | } 305 | 306 | /* Set up the socket data. */ 307 | inaddr.sin_family = host_ptr->h_addrtype; 308 | memcpy((char *)&inaddr.sin_addr, (char *)host_ptr->h_addr, sizeof(inaddr.sin_addr)); 309 | 310 | printf("inaddr = %08x\n", *(unsigned int *)&inaddr.sin_addr); 311 | } 312 | else 313 | { 314 | inaddr.sin_family = AF_INET; 315 | } 316 | 317 | inaddr.sin_port = htons(display_num + X_TCP_PORT); 318 | 319 | /* Open the network connection. */ 320 | // if ((fd = socket((int) addr->sa_family, SOCK_STREAM, 0)) < 0) 321 | // if ((fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 322 | if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 323 | { 324 | printf("socket failed\n"); 325 | return 0; 326 | } 327 | 328 | if (connect(fd, (struct sockaddr *) &inaddr, sizeof (struct sockaddr_in)) == -1) 329 | { 330 | printf("connect failed\n"); 331 | close(fd); 332 | return 0; 333 | } 334 | 335 | dpy = (Display *) malloc(sizeof(Display)); 336 | //if ???? 337 | memset(dpy, 0, sizeof(Display)); 338 | dpy->fd = fd; 339 | 340 | /* First byte is the byte order byte. Authentication key is normally sent right after the connection. 341 | This (in MIT's case) will be kerberos. */ 342 | i = 1; 343 | client.byteOrder = *((char *)&i) ? 'l' : 'B'; 344 | client.majorVersion = X_PROTOCOL; 345 | client.minorVersion = X_PROTOCOL_REVISION; 346 | client.nbytesAuthProto = 0; 347 | client.nbytesAuthString = 0; 348 | 349 | send(dpy->fd, (void *) &client, sizeof(xConnClientPrefix), 0); 350 | 351 | /* Now see if connection was accepted... */ 352 | recv(dpy->fd, (void *)&prefix, sizeof(xConnSetupPrefix), 0); 353 | 354 | if (prefix.majorVersion < X_PROTOCOL) 355 | { 356 | printf("Warning: Client built for newer server (prefix.majorVersion=%d < X_PROTOCOL=%d)!\n", prefix.majorVersion, X_PROTOCOL); 357 | } 358 | if (prefix.minorVersion != X_PROTOCOL_REVISION) 359 | { 360 | printf("Warning: Protocol rev. of client does not match server (prefix.minorVersion=%d != X_PROTOCOL_REVISION=%d)!\n", 361 | prefix.minorVersion, X_PROTOCOL_REVISION); 362 | } 363 | 364 | setuplength = prefix.length << 2; 365 | printf("setuplength = %ld\n", setuplength); 366 | setup = malloc(setuplength); 367 | 368 | recv(dpy->fd, setup, setuplength, 0); 369 | 370 | /* If the connection was not accepted by the server due to problems, give error message to the user... */ 371 | if (prefix.success != 1) 372 | { 373 | setup[prefix.lengthReason] = '\0'; 374 | printf("%s\n", setup); 375 | return 0; 376 | } 377 | 378 | p = setup; 379 | /* We succeeded at authorization, so let us move the data into the display structure. */ 380 | // dpy->next = (Display *) NULL; 381 | dpy->proto_major_version = prefix.majorVersion; 382 | dpy->proto_minor_version = prefix.minorVersion; 383 | dpy->release = ((xConnSetup *)p)->release; 384 | dpy->resource_base = ((xConnSetup *)p)->ridBase; 385 | dpy->resource_mask = ((xConnSetup *)p)->ridMask; 386 | dpy->min_keycode = ((xConnSetup *)p)->minKeyCode; 387 | dpy->max_keycode = ((xConnSetup *)p)->maxKeyCode; 388 | 389 | 390 | // dpy->keysyms = (KeySym *) NULL; 391 | //??? dpy->modifiermap = XNewModifiermap(0); 392 | // dpy->keysyms_per_keycode = 0; 393 | //??? dpy->current = None; 394 | // dpy->xdefaults = (char *)NULL; 395 | // dpy->scratch_length = 0L; 396 | // dpy->scratch_buffer = NULL; 397 | dpy->motion_buffer = ((xConnSetup *)p)->motionBufferSize; 398 | dpy->nformats = ((xConnSetup *)p)->numFormats; 399 | dpy->nscreens = ((xConnSetup *)p)->numRoots; 400 | dpy->byte_order = ((xConnSetup *)p)->imageByteOrder; 401 | dpy->bitmap_unit = ((xConnSetup *)p)->bitmapScanlineUnit; 402 | dpy->bitmap_pad = ((xConnSetup *)p)->bitmapScanlinePad; 403 | dpy->bitmap_bit_order = ((xConnSetup *)p)->bitmapBitOrder; 404 | dpy->max_request_size = ((xConnSetup *)p)->maxRequestSize; 405 | // dpy->ext_procs = (_XExtension *)NULL; 406 | // dpy->ext_data = (XExtData *)NULL; 407 | // dpy->ext_number = 0; 408 | #if 0 409 | dpy->event_vec[X_Error] = _XUnknownWireEvent; 410 | dpy->event_vec[X_Reply] = _XUnknownWireEvent; 411 | dpy->wire_vec[X_Error] = _XUnknownNativeEvent; 412 | dpy->wire_vec[X_Reply] = _XUnknownNativeEvent; 413 | for (i = KeyPress; i < LASTEvent; i++) { 414 | dpy->event_vec[i] = _XWireToEvent; 415 | dpy->wire_vec[i] = NULL; 416 | } 417 | for (i = LASTEvent; i < 128; i++) { 418 | dpy->event_vec[i] = _XUnknownWireEvent; 419 | dpy->wire_vec[i] = _XUnknownNativeEvent; 420 | } 421 | #endif 422 | // dpy->resource_id = 0; 423 | // dpy->resource_shift = ffs(dpy->resource_mask) - 1; 424 | 425 | printf("release = %d resource_base = %ld min_keycode = %d max_keycode = %d nformats = %d nscreens = %d byte_order = %d\n", 426 | dpy->release, 427 | dpy->resource_base, 428 | dpy->min_keycode, 429 | dpy->max_keycode, 430 | dpy->nformats, 431 | dpy->nscreens, 432 | dpy->byte_order); 433 | 434 | 435 | // for (i= dpy->resource_mask; i; i = (i>>1)) dpy->resource_shift++; 436 | for (i = 1, dpy->resource_shift = 0; dpy->resource_mask & i == 0; i = i<<1) dpy->resource_shift++; 437 | 438 | printf("resource_shift = %d resource_mask = %ld\n", dpy->resource_shift, dpy->resource_mask); 439 | 440 | // dpy->db = (struct _XrmResourceDataBase *)NULL; 441 | 442 | /* Initialize pointers to NULL so that XFreeDisplayStructure will work if we run out of memory */ 443 | 444 | // dpy->screens = NULL; 445 | // dpy->display_name = NULL; 446 | // dpy->buffer = NULL; 447 | 448 | /* now extract the vendor string... String must be null terminated,padded to multiple of 4 bytes. */ 449 | vendorlen = ((xConnSetup *)p)->nbytesVendor; 450 | dpy->vendor = malloc(vendorlen + 1); 451 | p += sizeof(xConnSetup); /* can't touch information in XConnSetup anymore..*/ 452 | memcpy(dpy->vendor, p, vendorlen); 453 | dpy->vendor[vendorlen] = '\0'; 454 | p += (vendorlen + 3) & ~3; 455 | 456 | printf("cool vendorlen =%d vendor = %s\n", vendorlen, dpy->vendor); 457 | 458 | 459 | /* Now iterate down setup information..... */ 460 | printf("nformats = %d\n", dpy->nformats); 461 | dpy->pixmap_format = (ScreenFormat *) malloc((unsigned) (dpy->nformats *sizeof(ScreenFormat))); 462 | 463 | /* First decode the Z axis Screen format information. */ 464 | for (i = 0; i < dpy->nformats; i++) 465 | { 466 | ScreenFormat *fmt = &dpy->pixmap_format[i]; 467 | fmt->depth = ((xPixmapFormat *) p)->depth; 468 | fmt->bits_per_pixel = ((xPixmapFormat *) p)->bitsPerPixel; 469 | fmt->scanline_pad = ((xPixmapFormat *) p)->scanLinePad; 470 | fmt->ext_data = NULL; 471 | 472 | printf("depth = %d bpp = %d pad = %d\n", fmt->depth, fmt->bits_per_pixel, fmt->scanline_pad); 473 | p += sizeof(xPixmapFormat); 474 | } 475 | 476 | /* next the Screen structures. */ 477 | printf("screens = %d\n",dpy->nscreens); 478 | dpy->screens = (Screen *) malloc((unsigned) dpy->nscreens * sizeof(Screen)); 479 | 480 | /* Now go deal with each screen structure. */ 481 | for (i = 0; i < dpy->nscreens; i++) 482 | { 483 | Screen *s = &dpy->screens[i]; 484 | VisualID root_visualID = ((xWindowRoot *) p)->rootVisualID; 485 | printf("root_visualID = %ld\n", root_visualID); 486 | 487 | s->display = dpy; 488 | s->root = ((xWindowRoot *) p)->windowId; 489 | s->cmap = ((xWindowRoot *) p)->defaultColormap; 490 | s->white_pixel = ((xWindowRoot *) p)->whitePixel; 491 | s->black_pixel = ((xWindowRoot *) p)->blackPixel; 492 | s->root_input_mask = ((xWindowRoot *) p)->currentInputMask; 493 | s->width = ((xWindowRoot *) p)->pixWidth; 494 | s->height = ((xWindowRoot *) p)->pixHeight; 495 | s->mwidth = ((xWindowRoot *) p)->mmWidth; 496 | s->mheight = ((xWindowRoot *) p)->mmHeight; 497 | s->min_maps = ((xWindowRoot *) p)->minInstalledMaps; 498 | s->max_maps = ((xWindowRoot *) p)->maxInstalledMaps; 499 | s->root_visual = NULL; /* filled in later, when we alloc Visuals */ 500 | s->backing_store= ((xWindowRoot *) p)->backingStore; 501 | s->save_unders = ((xWindowRoot *) p)->saveUnders; 502 | s->root_depth = ((xWindowRoot *) p)->rootDepth; 503 | s->ndepths = ((xWindowRoot *) p)->nDepths; 504 | // s->ext_data = NULL; 505 | p += sizeof(xWindowRoot); 506 | 507 | printf("screen %d root=%ld height=%d width=%d\n", i, s->root, s->height, s->width); 508 | 509 | /* lets set up the depth structures. */ 510 | s->depths = (Depth *) malloc(s->ndepths * sizeof(Depth)); 511 | 512 | /* for all depths on this screen. */ 513 | for (j = 0; j < s->ndepths; j++) 514 | { 515 | Depth *dp = &s->depths[j]; 516 | 517 | dp->depth = ((xDepth *) p)->depth; 518 | dp->nvisuals = ((xDepth *) p)->nVisuals; 519 | p += sizeof(xDepth); 520 | 521 | dp->visuals = (Visual *) malloc(dp->nvisuals * sizeof(Visual)); 522 | for (k = 0; k < dp->nvisuals; k++) 523 | { 524 | Visual *vp = &dp->visuals[k]; 525 | 526 | if ((vp->visualid = ((xVisualType *) p)->visualID) == root_visualID) s->root_visual = vp; 527 | vp->class = ((xVisualType *) p)->class; 528 | vp->bits_per_rgb= ((xVisualType *) p)->bitsPerRGB; 529 | vp->map_entries = ((xVisualType *) p)->colormapEntries; 530 | vp->red_mask = ((xVisualType *) p)->redMask; 531 | vp->green_mask = ((xVisualType *) p)->greenMask; 532 | vp->blue_mask = ((xVisualType *) p)->blueMask; 533 | vp->ext_data = NULL; 534 | p += sizeof(xVisualType); 535 | 536 | printf("screen %d depth %d visual %d: visualid=%ld class=%d bits_per_rgb=%d red_mask=%ld green_mask=%ld blue_mask=%ld\n", 537 | i,j,k, vp->visualid, vp->class, vp->bits_per_rgb, vp->red_mask, vp->green_mask, vp->blue_mask); 538 | } 539 | } 540 | } 541 | 542 | /* Setup other information in this display structure. */ 543 | // dpy->vnumber = X_PROTOCOL; 544 | //??? dpy->resource_alloc = _XAllocID; 545 | // dpy->synchandler = NULL; 546 | // dpy->request = 0; 547 | // dpy->last_request_read = 0; 548 | dpy->default_screen = screen_num; /* Value returned by ConnectDisplay */ 549 | 550 | #if 0 551 | /* Salt away the host:display string for later use */ 552 | if ((dpy->display_name = Xmalloc( 553 | (unsigned) (strlen(displaybuf) + 1))) == NULL) { 554 | OutOfMemory (dpy, setup); 555 | UnlockMutex(&lock); 556 | return(NULL); 557 | } 558 | (void) strcpy (dpy->display_name, displaybuf); 559 | 560 | #endif 561 | /* Set up the output buffers. */ 562 | dpy->bufptr = dpy->buffer = malloc(BUFSIZE); 563 | dpy->bufmax = dpy->buffer + BUFSIZE; 564 | 565 | /* Set up the input event queue and input event queue parameters. */ 566 | // dpy->head = dpy->tail = NULL; 567 | // dpy->qlen = 0; 568 | 569 | /* Now start talking to the server to setup all other information... */ 570 | 571 | free(setup); /* all finished with setup information */ 572 | 573 | /* Set up other stuff clients are always going to use. */ 574 | for (i = 0; i < dpy->nscreens; i++) 575 | { 576 | Screen *sp = &dpy->screens[i]; 577 | XGCValues values; 578 | values.foreground = sp->white_pixel; 579 | values.background = sp->black_pixel; 580 | sp->default_gc = XCreateGC(dpy, sp->root, GCForeground | GCBackground, &values); 581 | } 582 | 583 | /* call into synchronization routine so that all programs can be forced synchronize */ 584 | // XSynchronize(dpy, _Xdebug); 585 | 586 | /* chain this stucture onto global list. */ 587 | // dpy->next = _XHeadOfDisplayList; 588 | // _XHeadOfDisplayList = dpy; 589 | 590 | #if 0 591 | /* get the resource manager database off the root window. */ 592 | { 593 | Atom actual_type; 594 | int actual_format; 595 | unsigned long nitems; 596 | long leftover; 597 | if (XGetWindowProperty(dpy, RootWindow(dpy, 0), 598 | XA_RESOURCE_MANAGER, 0L, 100000000L, False, XA_STRING, 599 | &actual_type, &actual_format, &nitems, &leftover, 600 | &dpy->xdefaults) != Success) { 601 | dpy->xdefaults = (char *) NULL; 602 | } 603 | else { 604 | if ( (actual_type != XA_STRING) || (actual_format != 8) ) { 605 | if (dpy->xdefaults != NULL) Xfree ( dpy->xdefaults ); 606 | } 607 | } 608 | } 609 | #endif 610 | return dpy; 611 | } 612 | 613 | /* XCrGC.c */ 614 | 615 | /* 616 | * GenerateGCList looks at the GC dirty bits, and appends all the required 617 | * long words to the request being generated. Clears the dirty bits in the GC. 618 | */ 619 | void _XGenerateGCList(Display *dpy, GC gc, xReq *req) 620 | { 621 | /* Warning! This code assumes that "unsigned long" is 32-bits wide */ 622 | 623 | unsigned long values[32]; 624 | unsigned long *value = values; 625 | long nvalues; 626 | XGCValues *gv = &gc->values; 627 | unsigned long dirty = gc->dirty; 628 | 629 | /* Note: The order of these tests are critical; the order must be the same as the GC mask bits in the word. */ 630 | if (dirty & GCFunction) *value++ = gv->function; 631 | if (dirty & GCPlaneMask) *value++ = gv->plane_mask; 632 | if (dirty & GCForeground) *value++ = gv->foreground; 633 | if (dirty & GCBackground) *value++ = gv->background; 634 | if (dirty & GCLineWidth) *value++ = gv->line_width; 635 | if (dirty & GCLineStyle) *value++ = gv->line_style; 636 | if (dirty & GCCapStyle) *value++ = gv->cap_style; 637 | if (dirty & GCJoinStyle) *value++ = gv->join_style; 638 | if (dirty & GCFillStyle) *value++ = gv->fill_style; 639 | if (dirty & GCFillRule) *value++ = gv->fill_rule; 640 | if (dirty & GCTile) *value++ = gv->tile; 641 | if (dirty & GCStipple) *value++ = gv->stipple; 642 | if (dirty & GCTileStipXOrigin) *value++ = gv->ts_x_origin; 643 | if (dirty & GCTileStipYOrigin) *value++ = gv->ts_y_origin; 644 | if (dirty & GCFont) *value++ = gv->font; 645 | if (dirty & GCSubwindowMode) *value++ = gv->subwindow_mode; 646 | if (dirty & GCGraphicsExposures) *value++ = gv->graphics_exposures; 647 | if (dirty & GCClipXOrigin) *value++ = gv->clip_x_origin; 648 | if (dirty & GCClipYOrigin) *value++ = gv->clip_y_origin; 649 | if (dirty & GCClipMask) *value++ = gv->clip_mask; 650 | if (dirty & GCDashOffset) *value++ = gv->dash_offset; 651 | if (dirty & GCDashList) *value++ = gv->dashes; 652 | if (dirty & GCArcMode) *value++ = gv->arc_mode; 653 | 654 | req->length += (nvalues = value - values); 655 | 656 | nvalues <<= 2; 657 | 658 | if (dpy->bufptr + nvalues > dpy->bufmax) XFlush(dpy); 659 | memcpy(dpy->bufptr, values, nvalues); 660 | dpy->bufptr += nvalues; 661 | 662 | gc->dirty = 0L; 663 | } 664 | 665 | void FlushGC(Display *dpy, GC gc) 666 | { 667 | xChangeGCReq *r; 668 | 669 | if (gc->dirty) 670 | { 671 | printf("FlushGC()\n"); 672 | if (dpy->bufptr + sizeof(xChangeGCReq) > dpy->bufmax) XFlush(dpy); 673 | r = (xChangeGCReq *) dpy->bufptr; 674 | r->reqType = X_ChangeGC; 675 | r->length = sizeof(xChangeGCReq) >> 2; 676 | dpy->bufptr += sizeof(xChangeGCReq); 677 | dpy->request++; 678 | 679 | r->gc = gc->gid; 680 | r->mask = gc->dirty; 681 | 682 | _XGenerateGCList (dpy, gc, (xReq *) r); 683 | } 684 | } 685 | 686 | void _XUpdateGCCache (GC gc, long mask, XGCValues *att) 687 | { 688 | XGCValues *gv = &gc->values; 689 | 690 | if (mask & GCFunction && gv->function != att->function) { gv->function = att->function; gc->dirty |= GCFunction; } 691 | if (mask & GCPlaneMask && gv->plane_mask != att->plane_mask) { gv->plane_mask = att->plane_mask; gc->dirty |= GCPlaneMask; } 692 | if (mask & GCForeground && gv->foreground != att->foreground) { gv->foreground = att->foreground; gc->dirty |= GCForeground; } 693 | if (mask & GCBackground && gv->background != att->background) { gv->background = att->background; gc->dirty |= GCBackground; } 694 | if (mask & GCLineWidth && gv->line_width != att->line_width) { gv->line_width = att->line_width; gc->dirty |= GCLineWidth; } 695 | if (mask & GCLineStyle && gv->line_style != att->line_style) { gv->line_style = att->line_style; gc->dirty |= GCLineStyle; } 696 | if (mask & GCCapStyle && gv->cap_style != att->cap_style) { gv->cap_style = att->cap_style; gc->dirty |= GCCapStyle; } 697 | if (mask & GCJoinStyle && gv->join_style != att->join_style) { gv->join_style = att->join_style; gc->dirty |= GCJoinStyle; } 698 | if (mask & GCFillStyle && gv->fill_style != att->fill_style) { gv->fill_style = att->fill_style; gc->dirty |= GCFillStyle; } 699 | if (mask & GCFillRule && gv->fill_rule != att->fill_rule) { gv->fill_rule = att->fill_rule; gc->dirty |= GCFillRule; } 700 | if (mask & GCArcMode && gv->arc_mode != att->arc_mode) { gv->arc_mode = att->arc_mode; gc->dirty |= GCArcMode; } 701 | 702 | /* always write through resource ID changes */ 703 | if (mask & GCTile) { gv->tile = att->tile; gc->dirty |= GCTile; } 704 | 705 | /* always write through resource ID changes */ 706 | if (mask & GCStipple) { gv->stipple = att->stipple; gc->dirty |= GCStipple; } 707 | if (mask & GCTileStipXOrigin && gv->ts_x_origin != att->ts_x_origin) { gv->ts_x_origin = att->ts_x_origin; gc->dirty |= GCTileStipXOrigin; } 708 | if (mask & GCTileStipYOrigin && gv->ts_y_origin != att->ts_y_origin) { gv->ts_y_origin = att->ts_y_origin; gc->dirty |= GCTileStipYOrigin; } 709 | 710 | /* always write through resource ID changes */ 711 | if (mask & GCFont) { gv->font = att->font; gc->dirty |= GCFont; } 712 | if (mask & GCSubwindowMode && gv->subwindow_mode != att->subwindow_mode) { gv->subwindow_mode = att->subwindow_mode; gc->dirty |= GCSubwindowMode; } 713 | if (mask & GCGraphicsExposures && gv->graphics_exposures != att->graphics_exposures) { gv->graphics_exposures = att->graphics_exposures; gc->dirty |= GCGraphicsExposures; } 714 | if (mask & GCClipXOrigin && gv->clip_x_origin != att->clip_x_origin) { gv->clip_x_origin = att->clip_x_origin; gc->dirty |= GCClipXOrigin; } 715 | if (mask & GCClipYOrigin && gv->clip_y_origin != att->clip_y_origin) { gv->clip_y_origin = att->clip_y_origin; gc->dirty |= GCClipYOrigin; } 716 | if (mask & GCClipMask && (gv->clip_mask != att->clip_mask || gc->rects == 1)) { gv->clip_mask = att->clip_mask; gc->dirty |= GCClipMask; gc->rects = 0; } 717 | if (mask & GCDashOffset && gv->dash_offset != att->dash_offset) { gv->dash_offset = att->dash_offset; gc->dirty |= GCDashOffset; } 718 | if (mask & GCDashList && (gv->dashes != att->dashes || gc->dashes == 1)) { gv->dashes = att->dashes; gc->dirty |= GCDashList; gc->dashes = 0; } 719 | 720 | return; 721 | } 722 | 723 | GC XCreateGC( Display *dpy, Drawable d, /* Window or Pixmap for which depth matches */ 724 | unsigned long valuemask, /* which ones to set initially */ 725 | XGCValues *values) /* the values themselves */ 726 | { 727 | GC gc; 728 | xCreateGCReq *r; 729 | 730 | gc = (GC) malloc(sizeof(struct _XGC)); 731 | memset(gc, 0, sizeof(struct _XGC)); 732 | 733 | gc->values.function = GXcopy; 734 | gc->values.plane_mask = AllPlanes; 735 | gc->values.background = 1; 736 | gc->values.cap_style = CapButt; 737 | gc->values.arc_mode = ArcPieSlice; 738 | gc->values.tile = ~0; 739 | gc->values.stipple = ~0; 740 | gc->values.font = ~0; 741 | gc->values.graphics_exposures = 1; 742 | gc->values.dashes = 4; 743 | 744 | if (valuemask) _XUpdateGCCache (gc, valuemask, values); 745 | 746 | if (dpy->bufptr + sizeof(xCreateGCReq) > dpy->bufmax) XFlush(dpy); 747 | r = (xCreateGCReq *) dpy->bufptr; 748 | r->reqType = X_CreateGC; 749 | r->length = sizeof(xCreateGCReq) >> 2; 750 | dpy->bufptr += sizeof(xCreateGCReq); 751 | dpy->request++; 752 | 753 | r->drawable = d; 754 | r->gc = gc->gid = XAllocID(dpy); 755 | 756 | if ((r->mask = gc->dirty)) 757 | _XGenerateGCList (dpy, gc, (xReq *) r); 758 | 759 | printf("XCreateGC(%ld)\n",gc->gid); 760 | 761 | return gc; 762 | } 763 | 764 | void XChangeGC(Display *dpy, GC gc, unsigned long valuemask, XGCValues *values) 765 | { 766 | if (valuemask) _XUpdateGCCache (gc, valuemask, values); 767 | 768 | /* if any Resource ID changed, must flush */ 769 | if (valuemask & (GCFont | GCTile | GCStipple)) FlushGC(dpy, gc); 770 | } 771 | 772 | GContext XGContextFromGC(GC gc) 773 | { 774 | return (gc->gid); 775 | } 776 | 777 | Window XCreateSimpleWindow(Display *d, Window parent, int x, int y, int width, int height, int bwidth, unsigned long border, unsigned long background) 778 | { 779 | Window w; 780 | xCreateWindowReq *r; 781 | 782 | if (d->bufptr + sizeof(xCreateWindowReq) + 8 > d->bufmax) XFlush(d); 783 | r = (xCreateWindowReq *) d->bufptr; 784 | r->reqType = X_CreateWindow; 785 | r->length = (sizeof(xCreateWindowReq) + 8) >> 2; 786 | d->bufptr += sizeof(xCreateWindowReq) + 8; 787 | d->request++; 788 | 789 | r->parent = parent; 790 | r->x = x; 791 | r->y = y; 792 | r->width = width; 793 | r->height = height; 794 | r->borderWidth = bwidth; 795 | r->depth = 0; 796 | r->class = CopyFromParent; 797 | r->visual = CopyFromParent; 798 | 799 | w = r->wid = XAllocID(d); 800 | 801 | r->mask = CWBackPixel | CWBorderPixel; 802 | ((unsigned long *) (r+1))[0] = background; 803 | ((unsigned long *) (r+1))[1] = border; 804 | 805 | printf("XCreateSimpleWindow(%ld)\n",w); 806 | 807 | 808 | return (w); 809 | } 810 | 811 | void XSelectInput(Display *d, Window w, unsigned long mask) 812 | { 813 | xChangeWindowAttributesReq *r; 814 | printf("XSelectInput()\n"); 815 | 816 | if (d->bufptr + sizeof(xChangeWindowAttributesReq) + 4 > d->bufmax) XFlush(d); 817 | r = (xChangeWindowAttributesReq *) d->bufptr; 818 | r->reqType = X_ChangeWindowAttributes; 819 | r->length = (sizeof(xChangeWindowAttributesReq) + 4) >> 2; 820 | d->bufptr += sizeof(xChangeWindowAttributesReq) + 4; 821 | d->request++; 822 | 823 | r->window = w; 824 | r->valueMask = CWEventMask; 825 | ((unsigned long *) (r+1))[0] = mask; 826 | } 827 | 828 | void XMapWindow(Display *d, Window w) 829 | { 830 | xResourceReq *r; 831 | printf("XMapWindow()\n"); 832 | 833 | if (d->bufptr + sizeof(xResourceReq) > d->bufmax) XFlush(d); 834 | r = (xResourceReq *) d->bufptr; 835 | r->reqType = X_MapWindow; 836 | r->length = sizeof(xResourceReq) >> 2; 837 | r->id = w; 838 | d->bufptr += sizeof(xResourceReq); 839 | d->request++; 840 | } 841 | 842 | void XNextEvent(Display *d, XEvent *e) 843 | { 844 | XFlush(d); 845 | for (;;) 846 | { 847 | recv(d->fd, (char *) e, sizeof(XEvent), 0); 848 | printf("XNextEvent(ty=%d detail=%d seq=%d) p1=%ld p2=%ld\n", e->type, e->detail, e->sequence_number, e->p1, e->p2); 849 | if (e->type == X_Error) 850 | { 851 | printf("X_Error(resourceid = %ld, error_code = %d, minor_major_code = %ld)\n", e->p1, e->detail, e->p2); 852 | //continue; 853 | break; 854 | } 855 | else 856 | break; 857 | } 858 | } 859 | 860 | void XFillRectangle(Display *d, Window win, GC gc, int x, int y, int w, int h) 861 | { 862 | xPolyFillRectangleReq *r; 863 | printf("XFillRectangle()\n"); 864 | if (gc->dirty) FlushGC(d, gc); 865 | 866 | if (d->bufptr + sizeof(xPolyFillRectangleReq) + sizeof(xRectangle) > d->bufmax) XFlush(d); 867 | r = (xPolyFillRectangleReq *) d->bufptr; 868 | r->reqType = X_PolyFillRectangle; 869 | r->length = (sizeof(xPolyFillRectangleReq) + sizeof(xRectangle)) >> 2; 870 | d->bufptr += sizeof(xPolyFillRectangleReq) + sizeof(xRectangle); 871 | d->request++; 872 | 873 | r->drawable = win; 874 | r->gc = gc->gid; 875 | ((xRectangle *) (r+1))->x = x; 876 | ((xRectangle *) (r+1))->y = y; 877 | ((xRectangle *) (r+1))->width = w; 878 | ((xRectangle *) (r+1))->height = h; 879 | } 880 | 881 | void XDrawString(Display *dpy, Drawable d, GC gc, int x, int y, char *string, int length) 882 | { 883 | int Datalength; 884 | xPolyText8Req *r; 885 | int nbytes; 886 | int PartialNChars; 887 | xTextElt *elt; 888 | char *CharacterOffset; 889 | 890 | printf("XDrawString()\n"); 891 | 892 | if (length <= 0) 893 | return; 894 | 895 | if (dpy->bufptr + sizeof(xPolyText8Req) > dpy->bufmax) XFlush(dpy); 896 | r = (xPolyText8Req *) dpy->bufptr; 897 | r->reqType = X_PolyText8; 898 | r->length = sizeof(xPolyText8Req) >> 2; 899 | dpy->bufptr += sizeof(xPolyText8Req); 900 | dpy->request++; 901 | 902 | r->drawable = d; 903 | r->gc = gc->gid; 904 | r->x = x; 905 | r->y = y; 906 | 907 | Datalength = sizeof(xTextElt) * ((length + 253) / 254) + length; 908 | 909 | r->length += (Datalength + 3)>>2; /* convert to number of 32-bit words */ 910 | 911 | /* 912 | * If the entire request does not fit into the remaining space in the 913 | * buffer, flush the buffer first. If the request does fit into the 914 | * empty buffer, then we won't have to flush it at the end to keep 915 | * the buffer 32-bit aligned. 916 | */ 917 | 918 | if (dpy->bufptr + Datalength > dpy->bufmax) 919 | XFlush (dpy); 920 | 921 | PartialNChars = length; 922 | CharacterOffset = string; 923 | 924 | while(PartialNChars > 254) 925 | { 926 | nbytes = 254 + sizeof(xTextElt); 927 | 928 | // BufAlloc (xTextElt *, elt, nbytes); 929 | if (dpy->bufptr + nbytes > dpy->bufmax) XFlush(dpy); 930 | elt = (xTextElt *) dpy->bufptr; 931 | dpy->bufptr += nbytes; 932 | 933 | elt->delta = 0; 934 | elt->len = 254; 935 | memcpy((char *) (elt + 1), CharacterOffset, 254); 936 | PartialNChars = PartialNChars - 254; 937 | CharacterOffset += 254; 938 | } 939 | 940 | if (PartialNChars) 941 | { 942 | nbytes = PartialNChars + sizeof(xTextElt); 943 | 944 | // BufAlloc (xTextElt *, elt, nbytes); 945 | if (dpy->bufptr + nbytes > dpy->bufmax) XFlush(dpy); 946 | elt = (xTextElt *) dpy->bufptr; 947 | dpy->bufptr += nbytes; 948 | 949 | elt->delta = 0; 950 | elt->len = PartialNChars; 951 | memcpy((char *) (elt + 1), CharacterOffset, PartialNChars); 952 | } 953 | 954 | /* Pad request out to a 32-bit boundary */ 955 | 956 | if (Datalength &= 3) 957 | { 958 | char *pad; 959 | /* 960 | * BufAlloc is a macro that uses its last argument more than 961 | * once, otherwise I'd write "BufAlloc (char *, pad, 4-length)" 962 | */ 963 | length = 4 - Datalength; 964 | 965 | // BufAlloc (char *, pad, length); 966 | if (dpy->bufptr + length > dpy->bufmax) XFlush(dpy); 967 | pad = (char *) dpy->bufptr; 968 | dpy->bufptr += length; 969 | 970 | /* 971 | * if there are 3 bytes of padding, the first byte MUST be 0 972 | * so the pad bytes aren't mistaken for a final xTextElt 973 | */ 974 | *pad = 0; 975 | } 976 | 977 | /* 978 | * If the buffer pointer is not now pointing to a 32-bit boundary, 979 | * we must flush the buffer so that it does point to a 32-bit boundary 980 | * at the end of this routine. 981 | */ 982 | 983 | if ((dpy->bufptr - dpy->buffer) & 3) 984 | XFlush (dpy); 985 | 986 | } 987 | 988 | 989 | 990 | 991 | void XCloseDisplay(Display *d) 992 | { 993 | #ifdef WIN32 994 | closesocket(d->fd); 995 | WSACleanup(); 996 | #else 997 | close(d->fd); 998 | #endif 999 | } 1000 | 1001 | #if 0 //??????????????????? 1002 | 1003 | /* 1004 | * GetReq - Get the next avilable X request packet in the buffer and 1005 | * return it. 1006 | * 1007 | * "name" is the name of the request, e.g. CreatePixmap, OpenFont, etc. 1008 | * "req" is the name of the request pointer. 1009 | * 1010 | */ 1011 | 1012 | #define GetReq(name, req) \ 1013 | if ((dpy->bufptr + sizeof(x/**/name/**/Req)) > dpy->bufmax)\ 1014 | _XFlush(dpy);\ 1015 | req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ 1016 | req->reqType = X_/**/name;\ 1017 | req->length = (sizeof(x/**/name/**/Req))>>2;\ 1018 | dpy->bufptr += sizeof(x/**/name/**/Req);\ 1019 | dpy->request++ 1020 | 1021 | /* GetReqExtra is the same as GetReq, but allocates "n" additional 1022 | bytes after the request. "n" must be a multiple of 4! */ 1023 | 1024 | 1025 | #define GetReqExtra(name, n, req) \ 1026 | if ((dpy->bufptr + sizeof(x/**/name/**/Req) + n) > dpy->bufmax)\ 1027 | _XFlush(dpy);\ 1028 | req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ 1029 | req->reqType = X_/**/name;\ 1030 | req->length = (sizeof(x/**/name/**/Req) + n)>>2;\ 1031 | dpy->bufptr += sizeof(x/**/name/**/Req) + n;\ 1032 | dpy->request++ 1033 | 1034 | /* 1035 | * GetResReq is for those requests that have a resource ID 1036 | * (Window, Pixmap, GContext, etc.) as their single argument. 1037 | * "rid" is the name of the resource. 1038 | */ 1039 | 1040 | #define GetResReq(name, rid, req) \ 1041 | if ((dpy->bufptr + sizeof(xResourceReq)) > dpy->bufmax)\ 1042 | _XFlush(dpy);\ 1043 | req = (xResourceReq *) (dpy->last_req = dpy->bufptr);\ 1044 | req->reqType = X_/**/name;\ 1045 | req->length = 2;\ 1046 | req->id = (rid);\ 1047 | dpy->bufptr += sizeof(xResourceReq);\ 1048 | dpy->request++ 1049 | 1050 | /* 1051 | * GetEmptyReq is for those requests that have no arguments 1052 | * at all. 1053 | */ 1054 | 1055 | #define GetEmptyReq(name, req) \ 1056 | if ((dpy->bufptr + sizeof(xReq)) > dpy->bufmax)\ 1057 | _XFlush(dpy);\ 1058 | req = (xReq *) (dpy->last_req = dpy->bufptr);\ 1059 | req->reqType = X_/**/name;\ 1060 | req->length = 1;\ 1061 | dpy->bufptr += sizeof(xReq);\ 1062 | dpy->request++ 1063 | 1064 | #define SyncHandle() \ 1065 | if (dpy->synchandler) (*dpy->synchandler)(dpy) 1066 | 1067 | #define FlushGC(dpy, gc) \ 1068 | if ((gc)->dirty) _XFlushGCCache((dpy), (gc)) 1069 | /* 1070 | * Data - Place data in the buffer and pad the end to provide 1071 | * 32 bit word alignment. Transmit if the buffer fills. 1072 | * 1073 | * "dpy" is a pointer to a Display. 1074 | * "data" is a pinter to a data buffer. 1075 | * "len" is the length of the data buffer. 1076 | * we can presume buffer less than 2^16 bytes, so bcopy can be used safely. 1077 | */ 1078 | #define Data(dpy, data, len) \ 1079 | if (dpy->bufptr + (len) <= dpy->bufmax) {\ 1080 | bcopy(data, dpy->bufptr, (int)len);\ 1081 | dpy->bufptr += ((len) + 3) & ~3;\ 1082 | } else\ 1083 | _XSend(dpy, data, len) 1084 | 1085 | 1086 | /* Allocate bytes from the buffer. No padding is done, so if 1087 | * the length is not a multiple of 4, the caller must be 1088 | * careful to leave the buffer aligned after sending the 1089 | * current request. 1090 | * 1091 | * "type" is the type of the pointer being assigned to. 1092 | * "ptr" is the pointer being assigned to. 1093 | * "n" is the number of bytes to allocate. 1094 | * 1095 | * Example: 1096 | * xTextElt *elt; 1097 | * BufAlloc (xTextElt *, elt, nbytes) 1098 | */ 1099 | 1100 | #define BufAlloc(type, ptr, n) \ 1101 | if (dpy->bufptr + (n) > dpy->bufmax) \ 1102 | _XFlush (dpy); \ 1103 | ptr = (type) dpy->bufptr; \ 1104 | dpy->bufptr += (n); 1105 | 1106 | #ifndef BIGSHORTS 1107 | #define PackData(dpy, data, len) Data(dpy, data, len) 1108 | #define PackShorts(f, t, n) bcopy(f, t, n) 1109 | #endif 1110 | 1111 | #endif 1112 | 1113 | 1114 | -------------------------------------------------------------------------------- /example.c: -------------------------------------------------------------------------------- 1 | /* Simple Xlib application drawing a box in a window. */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main() 9 | { 10 | Display *d; 11 | int s; 12 | Window w; 13 | XEvent e; 14 | 15 | // d = XOpenDisplay(NULL); 16 | d = XOpenDisplay("127.0.0.1:0.0"); 17 | // d = XOpenDisplay("192.168.58.2:1"); 18 | 19 | if(!d) 20 | { 21 | printf("Cannot open display\n"); 22 | exit(1); 23 | } 24 | 25 | s = DefaultScreen(d); 26 | 27 | printf("default screen=%d rootwindow=%ld\n", s, RootWindow(d,s)); 28 | 29 | //exit(9); 30 | 31 | /* create window */ 32 | w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 100, 100, 1, 33 | WhitePixel(d, s), BlackPixel(d, s)); 34 | 35 | // XNextEvent(d, &e); 36 | // exit(9); 37 | 38 | /* select kind of events we are interested in */ 39 | XSelectInput(d, w, ExposureMask | KeyPressMask); 40 | 41 | // XNextEvent(d, &e); 42 | // exit(9); 43 | 44 | /* map (show) the window */ 45 | XMapWindow(d, w); 46 | 47 | // XNextEvent(d, &e); 48 | // exit(9); 49 | 50 | /* event loop */ 51 | for (;;) 52 | { 53 | XNextEvent(d, &e); 54 | 55 | // exit(9); 56 | 57 | /* draw or redraw the window */ 58 | if (e.type==Expose) 59 | { 60 | XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10); 61 | XDrawString(d, w, DefaultGC(d, s), 50, 50, "Hello, World!",strlen("Hello, World!")); 62 | } 63 | 64 | /* exit on key press */ 65 | if(e.type==KeyPress) 66 | break; 67 | } 68 | 69 | /* close connection to server */ 70 | XCloseDisplay(d); 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /m.sh: -------------------------------------------------------------------------------- 1 | gcc -m32 -I. -o example example.c XLib.c 2 | gcc -o xexample example.c -L/usr/X11R6/lib -lX11 3 | --------------------------------------------------------------------------------