📄 xlibint.c
字号:
{ 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 dpybufsize = (dpy->bufptr - dpy->buffer); long padsize = padlength[size & 3]; long total = dpybufsize + size + padsize; long todo = total; if (dpy->flags & XlibDisplayIOError) return; /* * There are 3 pieces that may need to be written out: * * o whatever is in the display buffer * o the data passed in by the user * o any padding needed to 32bit align the whole mess * * This loop looks at all 3 pieces each time through. It uses skip * to figure out whether or not a given piece is needed. */ while (total) { long before = skip; /* amount of whole thing written */ long remain = todo; /* amount to try this time, <= total */ 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. This * translates to: * * how much of this piece is new? * if more new then we are trying this time, clamp * if nothing new * then bump down amount already written, for next piece * else put new stuff in iovec, will need all of next piece * * Note that todo had better be at least 1 or else we'll end up * writing 0 iovecs. */#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, dpybufsize) InsertIOV (data, size) InsertIOV (pad, padsize) errno = 0; if ((len = WritevToServer(dpy->fd, iov, i)) >= 0) { skip += len; total -= len; todo = total; } else if (ETEST(errno)) { _XWaitForWritable(dpy);#ifdef SUNSYSV } else if (errno == 0) { _XWaitForWritable(dpy);#endif#ifdef EMSGSIZE } else if (errno == EMSGSIZE) { if (todo > 1) todo >>= 1; else _XWaitForWritable(dpy);#endif } else if (errno != EINTR) { _XIOError(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;{ XID id; id = dpy->resource_id << dpy->resource_shift; if (id <= dpy->resource_mask) { dpy->resource_id++; return (dpy->resource_base + id); } if (id != 0x10000000) { (void) fprintf(stderr, "Xlib: resource ID allocation space exhausted!\n"); id = 0x10000000; dpy->resource_id = id >> dpy->resource_shift; } return id;}/* * 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. */unsigned long_XSetLastRequestRead(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 following "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; if (dpy->flags & XlibDisplayIOError) return (0); _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) _XSetLastRequestRead(dpy, &rep->generic); if (extra == 0) { if (discard && (rep->generic.length > 0)) /* unexpectedly long reply! */ _EatData32 (dpy, rep->generic.length); return (1); } if (extra == rep->generic.length) { /* * Read the extra data into storage immediately following * the GenericReply structure. */ _XRead (dpy, (char *) (NEXTPTR(rep,xReply)), ((long)extra) << 2); return (1); } if (extra < rep->generic.length) { /* Actual reply is longer than "extra" */ _XRead (dpy, (char *) (NEXTPTR(rep,xReply)), ((long)extra) << 2); if (discard) _EatData32 (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, (char *) (NEXTPTR(rep,xReply)), ((long) rep->generic.length) << 2); _XIOError (dpy); return (0); case X_Error: { register _XExtension *ext; register Bool ret = False; int ret_code; xError *err = (xError *) rep; unsigned long serial; serial = _XSetLastRequestRead(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. */ for (ext = dpy->ext_procs; !ret && ext; ext = ext->next) { if (ext->error) ret = (*ext->error)(dpy, err, &ext->codes, &ret_code); } if (!ret) { _XError(dpy, err); ret_code = 0; } if (serial == cur_request) return(ret_code); } break; default: _XEnq(dpy, (xEvent *) rep); break; } }} /* Read and discard "n" 8-bit bytes of data */void _XEatData (dpy, n) Display *dpy; register unsigned long n;{#define SCRATCHSIZE 2048 char buf[SCRATCHSIZE]; while (n > 0) { register long bytes_read = (n > SCRATCHSIZE) ? SCRATCHSIZE : n; _XRead (dpy, buf, bytes_read); n -= bytes_read; }#undef SCRATCHSIZE}/* Read and discard "n" 32-bit words. */static void _EatData32 (dpy, n) Display *dpy; unsigned long n;{ _XEatData (dpy, n << 2);}/* * _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; _XIOError(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 = _XSetLastRequestRead(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 = cvtINT16toInt(event->u.keyButtonPointer.eventX); ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); ev->y_root = cvtINT16toInt(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 = cvtINT16toInt(event->u.keyButtonPointer.eventX); ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); ev->y_root = cvtINT16toInt(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 = cvtINT16toInt(event->u.keyButtonPointer.eventX); ev->y = cvtINT16toInt(event->u.keyButtonPointer.eventY); ev->x_root = cvtINT16toInt(event->u.keyButtonPointer.rootX); ev->y_root = cvtINT16toInt(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 = cvtINT16toInt(event->u.enterLeave.eventX); ev->y = cvtINT16toInt(event->u.enterLeave.eventY); ev->x_root = cvtINT16toInt(event->u.enterLeave.rootX); ev->y_root = cvtINT16toInt(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; ev->window = event->u.expose.window; ev->x = event->u.expose.x; ev->y = event->u.expose.y; ev->width = event->u.expose.width; ev->height = event->u.expose.height; ev->count = event->u.expose.count; } break; case GraphicsExpose: { register XGraphicsExposeEvent *ev = (XGraphicsExposeEvent *) re;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -