📄 xlibint.c
字号:
unsigned nwords = (PACKBUFFERSIZE >> 2); /* bytes to CARD32 */ for (; len > nwords; len -= nwords, data += nwords) { _doXRead32 (dpy, data, nwords, packbuffer); } _doXRead32 (dpy, data, len, packbuffer);}/* * _XRead16 - Read bytes from the socket unpacking each 16 bits * into a long (64 bits on a CRAY computer). * */static _doXRead16 (dpy, data, size, packbuffer) register Display *dpy; register short *data; register long size; char *packbuffer;{ long *lpack,*lp; long mask16 = 0x000000000000ffff; long maskw, nwords, i, bits; _XRead(dpy,packbuffer,size); /* don't do a padded read... */ lp = (long *) data; lpack = (long *) packbuffer; nwords = size >> 1; /* number of 16 bit words to be unpacked */ bits = 48; for(i=0;i<nwords;i++){ maskw = mask16 << bits; *lp++ = ( *lpack & maskw ) >> bits; bits -= 16; if(bits < 0){ lpack++; bits = 48; } }}_XRead16 (dpy, data, len) Display *dpy; short *data; long len;{ char packbuffer[PACKBUFFERSIZE]; unsigned nwords = (PACKBUFFERSIZE >> 1); /* bytes to CARD16 */ for (; len > nwords; len -= nwords, data += nwords) { _doXRead16 (dpy, data, nwords, packbuffer); } _doXRead16 (dpy, data, len, packbuffer);}_XRead16Pad (dpy, data, size) Display *dpy; short *data; long size;{ int slop = (size & 3); short slopbuf[3]; _XRead16 (dpy, data, size); if (slop > 0) { _XRead16 (dpy, slopbuf, 4 - slop); }}#endif /* WORD64 *//* * _XReadPad - Read bytes from the socket taking into account incomplete * reads. If the number of bytes is not 0 mod 32, read additional pad * bytes. This routine may have to be reworked if int < long. */_XReadPad (dpy, data, size) register Display *dpy; register char *data; register long size;{ register long bytes_read; struct iovec iov[2]; char pad[3]; if (size == 0) return; iov[0].iov_len = (int)size; iov[0].iov_base = data; /* * The following hack is used to provide 32 bit long-word * aligned padding. The [1] vector is of length 0, 1, 2, or 3, * whatever is needed. */ iov[1].iov_len = padlength[size & 3]; iov[1].iov_base = pad; size += iov[1].iov_len; errno = 0; while ((bytes_read = ReadvFromServer (dpy->fd, iov, 2)) != size) { if (bytes_read > 0) { size -= bytes_read; if ((iov[0].iov_len -= bytes_read) < 0) { iov[1].iov_len += iov[0].iov_len; iov[1].iov_base -= iov[0].iov_len; iov[0].iov_len = 0; } else iov[0].iov_base += bytes_read; }#ifdef EWOULDBLOCK else if (errno == EWOULDBLOCK) { _XWaitForReadable(dpy); errno = 0; }#endif#ifdef SUNSYSV else if (errno == 0) { _XWaitForReadable(dpy); }#endif else if (bytes_read == 0) { /* Read failed because of end of file! */ errno = EPIPE; (*_XIOErrorFunction)(dpy); } else /* bytes_read is less than 0; presumably -1 */ { /* If it's a system call interrupt, it's not an error. */ if (errno != EINTR) (*_XIOErrorFunction)(dpy); } }}/* * _XSend - Flush the buffer and send the client data. 32 bit word aligned * transmission is used, if size is not 0 mod 4, extra bytes are transmitted. * This routine may have to be reworked if int < long; */_XSend (dpy, data, size) register Display *dpy; char *data; register long size;{ struct iovec iov[3]; static char pad[3] = {0, 0, 0}; /* XText8 and XText16 require that the padding bytes be zero! */ long skip = 0; long total = (dpy->bufptr - dpy->buffer) + ((size + 3) & ~3); long todo = total; while (total) { long before = skip; long remain = todo; int i = 0; long len; /* You could be very general here and have "in" and "out" iovecs * and write a loop without using a macro, but what the heck */#define InsertIOV(pointer, length) \ len = (length) - before; \ if (len > remain) \ len = remain; \ if (len <= 0) { \ before = -len; \ } else { \ iov[i].iov_len = len; \ iov[i].iov_base = (pointer) + before; \ i++; \ remain -= len; \ before = 0; \ } InsertIOV(dpy->buffer, dpy->bufptr - dpy->buffer) InsertIOV(data, size) /* Provide 32-bit aligned padding as necessary */ InsertIOV(pad, padlength[size & 3]) errno = 0; if ((len = WritevToServer(dpy->fd, iov, i)) >= 0) { skip += len; total -= len; todo = total;#ifdef EWOULDBLOCK } else if (errno == EWOULDBLOCK) { _XWaitForWritable(dpy);#endif#ifdef SUNSYSV } else if (errno == 0) { _XWaitForWritable(dpy);#endif#ifdef EMSGSIZE } else if (errno == EMSGSIZE) { todo = todo >> 1;#endif } else { (*_XIOErrorFunction)(dpy); } } dpy->bufptr = dpy->buffer; dpy->last_req = (char *) & _dummy_request;}/* * _XAllocID - normal resource ID allocation routine. A client * can roll his own and instatantiate it if he wants, but must * follow the rules. */XID _XAllocID(dpy)register Display *dpy;{ return (dpy->resource_base + (dpy->resource_id++ << dpy->resource_shift));}/* * The hard part about this is that we only get 16 bits from a reply. Well, * then, we have three values that will march along, with the following * invariant: * dpy->last_request_read <= rep->sequenceNumber <= dpy->request * The right choice for rep->sequenceNumber is the largest that * still meets these constraints. */static unsigned long_SetLastRequestRead(dpy, rep) register Display *dpy; register xGenericReply *rep;{ register unsigned long newseq, lastseq; /* * KeymapNotify has no sequence number, but is always guaranteed * to immediately follow another event, except when generated via * SendEvent (hmmm). */ if ((rep->type & 0x7f) == KeymapNotify) return(dpy->last_request_read); newseq = (dpy->last_request_read & ~((unsigned long)0xffff)) | rep->sequenceNumber; lastseq = dpy->last_request_read; while (newseq < lastseq) { newseq += 0x10000; if (newseq > dpy->request) { (void) fprintf (stderr, "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n", newseq, dpy->request, (unsigned int) rep->type); newseq -= 0x10000; break; } } dpy->last_request_read = newseq; return(newseq);}/* * _XReply - Wait for a reply packet and copy its contents into the * specified rep. Mean while we must handle error and event packets that * we may encounter. */Status _XReply (dpy, rep, extra, discard) register Display *dpy; register xReply *rep; int extra; /* number of 32-bit words expected after the reply */ Bool discard; /* should I discard data followind "extra" words? */{ /* Pull out the serial number now, so that (currently illegal) requests * generated by an error handler don't confuse us. */ unsigned long cur_request = dpy->request; _XFlush(dpy); while (1) { _XRead(dpy, (char *)rep, (long)SIZEOF(xReply)); switch ((int)rep->generic.type) { case X_Reply: /* Reply received. Fast update for synchronous replies, * but deal with multiple outstanding replies. */ if (rep->generic.sequenceNumber == (cur_request & 0xffff)) dpy->last_request_read = cur_request; else (void) _SetLastRequestRead(dpy, &rep->generic); if (extra == 0) { if (discard && (rep->generic.length > 0)) /* unexpectedly long reply! */ _EatData (dpy, rep->generic.length); return (1); } if (extra == rep->generic.length) { /* * Read the extra data into storage immediately following * the GenericReply structure. */ _XRead (dpy, NEXTPTR(rep,xReply), ((long)extra) << 2); return (1); } if (extra < rep->generic.length) { /* Actual reply is longer than "extra" */ _XRead (dpy, NEXTPTR(rep,xReply), ((long)extra) << 2); if (discard) _EatData (dpy, rep->generic.length - extra); return (1); } /* *if we get here, then extra > rep->generic.length--meaning we * read a reply that's shorter than we expected. This is an * error, but we still need to figure out how to handle it... */ _XRead (dpy, NEXTPTR(rep,xReply), ((long) rep->generic.length) << 2); (*_XIOErrorFunction) (dpy); return (0); case X_Error: { register _XExtension *ext; register Bool ret = False; int ret_code; xError *err = (xError *) rep; unsigned long serial; serial = _SetLastRequestRead(dpy, (xGenericReply *)rep); if (serial == cur_request) /* do not die on "no such font", "can't allocate", "can't grab" failures */ switch ((int)err->errorCode) { case BadName: switch (err->majorCode) { case X_OpenFont: case X_LookupColor: case X_AllocNamedColor: return(0); } break; case BadFont: if (err->majorCode == X_QueryFont) return (0); break; case BadAlloc: case BadAccess: return (0); /* * we better see if there is an extension who may * want to suppress the error. */ default: ext = dpy->ext_procs; while (ext) { if (ext->error != NULL) ret = (*ext->error) (dpy, err, &ext->codes, &ret_code); ext = ext->next; } if (ret) return (ret_code); break; } _XError(dpy, err); if (serial == cur_request) return(0); } break; default: _XEnq(dpy, (xEvent *) rep); break; } }} /* Read and discard "n" 32-bit words. */static _EatData (dpy, n) Display *dpy; unsigned long n; { unsigned int bufsize; char *buf; n <<= 2; /* convert to number of bytes */ buf = Xmalloc (bufsize = (n > 2048) ? 2048 : n); while (n) { long bytes_read = (n > bufsize) ? bufsize : n; _XRead (dpy, buf, bytes_read); n -= bytes_read; } Xfree (buf); }/* * _XEnq - Place event packets on the display's queue. * note that no squishing of move events in V11, since there * is pointer motion hints.... */_XEnq (dpy, event) register Display *dpy; register xEvent *event;{ register _XQEvent *qelt;/*NOSTRICT*/ if (qelt = _qfree) { /* If _qfree is non-NULL do this, else malloc a new one. */ _qfree = qelt->next; } else if ((qelt = (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) { /* Malloc call failed! */ errno = ENOMEM; (*_XIOErrorFunction)(dpy); } qelt->next = NULL; /* go call through display to find proper event reformatter */ if ((*dpy->event_vec[event->u.u.type & 0177])(dpy, &qelt->event, event)) { if (dpy->tail) dpy->tail->next = qelt; else dpy->head = qelt; dpy->tail = qelt; dpy->qlen++; } else { /* ignored, or stashed away for many-to-one compression */ qelt->next = _qfree; _qfree = qelt; }}/* * EventToWire in separate file in that often not needed. *//*ARGSUSED*/Bool_XUnknownWireEvent(dpy, re, event)register Display *dpy; /* pointer to display structure */register XEvent *re; /* pointer to where event should be reformatted */register xEvent *event; /* wire protocol event */{#ifdef notdef (void) fprintf(stderr, "Xlib: unhandled wire event! event number = %d, display = %x\n.", event->u.u.type, dpy);#endif return(False);}/*ARGSUSED*/Status_XUnknownNativeEvent(dpy, re, event)register Display *dpy; /* pointer to display structure */register XEvent *re; /* pointer to where event should be reformatted */register xEvent *event; /* wire protocol event */{#ifdef notdef (void) fprintf(stderr, "Xlib: unhandled native event! event number = %d, display = %x\n.", re->type, dpy);#endif return(0);}/* * reformat a wire event into an XEvent structure of the right type. */Bool_XWireToEvent(dpy, re, event)register Display *dpy; /* pointer to display structure */register XEvent *re; /* pointer to where event should be reformatted */register xEvent *event; /* wire protocol event */{ re->type = event->u.u.type & 0x7f; ((XAnyEvent *)re)->serial = _SetLastRequestRead(dpy, (xGenericReply *)event); ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0); ((XAnyEvent *)re)->display = dpy; /* Ignore the leading bit of the event type since it is set when a client sends an event rather than the server. */ switch (event-> u.u.type & 0177) { case KeyPress: case KeyRelease: { register XKeyEvent *ev = (XKeyEvent*) re; ev->root = event->u.keyButtonPointer.root; ev->window = event->u.keyButtonPointer.event; ev->subwindow = event->u.keyButtonPointer.child; ev->time = event->u.keyButtonPointer.time; ev->x = event->u.keyButtonPointer.eventX; ev->y = event->u.keyButtonPointer.eventY; ev->x_root = event->u.keyButtonPointer.rootX; ev->y_root = event->u.keyButtonPointer.rootY; ev->state = event->u.keyButtonPointer.state; ev->same_screen = event->u.keyButtonPointer.sameScreen; ev->keycode = event->u.u.detail; } break; case ButtonPress: case ButtonRelease: { register XButtonEvent *ev = (XButtonEvent *) re; ev->root = event->u.keyButtonPointer.root; ev->window = event->u.keyButtonPointer.event; ev->subwindow = event->u.keyButtonPointer.child; ev->time = event->u.keyButtonPointer.time; ev->x = event->u.keyButtonPointer.eventX; ev->y = event->u.keyButtonPointer.eventY; ev->x_root = event->u.keyButtonPointer.rootX; ev->y_root = event->u.keyButtonPointer.rootY; ev->state = event->u.keyButtonPointer.state; ev->same_screen = event->u.keyButtonPointer.sameScreen; ev->button = event->u.u.detail; } break; case MotionNotify: { register XMotionEvent *ev = (XMotionEvent *)re; ev->root = event->u.keyButtonPointer.root; ev->window = event->u.keyButtonPointer.event; ev->subwindow = event->u.keyButtonPointer.child; ev->time = event->u.keyButtonPointer.time; ev->x = event->u.keyButtonPointer.eventX; ev->y = event->u.keyButtonPointer.eventY; ev->x_root = event->u.keyButtonPointer.rootX; ev->y_root = event->u.keyButtonPointer.rootY; ev->state = event->u.keyButtonPointer.state; ev->same_screen = event->u.keyButtonPointer.sameScreen; ev->is_hint = event->u.u.detail; } break; case EnterNotify: case LeaveNotify: { register XCrossingEvent *ev = (XCrossingEvent *) re; ev->root = event->u.enterLeave.root; ev->window = event->u.enterLeave.event; ev->subwindow = event->u.enterLeave.child; ev->time = event->u.enterLeave.time; ev->x = event->u.enterLeave.eventX; ev->y = event->u.enterLeave.eventY; ev->x_root = event->u.enterLeave.rootX; ev->y_root = event->u.enterLeave.rootY; ev->state = event->u.enterLeave.state; ev->mode = event->u.enterLeave.mode; ev->same_screen = (event->u.enterLeave.flags & ELFlagSameScreen) && True; ev->focus = (event->u.enterLeave.flags & ELFlagFocus) && True; ev->detail = event->u.u.detail; } break; case FocusIn: case FocusOut: { register XFocusChangeEvent *ev = (XFocusChangeEvent *) re; ev->window = event->u.focus.window; ev->mode = event->u.focus.mode; ev->detail = event->u.u.detail; } break; case KeymapNotify: { register XKeymapEvent *ev = (XKeymapEvent *) re; ev->window = dpy->current; bcopy ((char *)((xKeymapEvent *) event)->map, &ev->key_vector[1], sizeof (((xKeymapEvent *) event)->map)); } break; case Expose: { register XExposeEvent *ev = (XExposeEvent *) re;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -