static gboolean ungrabKey(MyKey *key) { Window root = GDK_ROOT_WINDOW(); Display *dpy = GDK_DISPLAY(); gdk_error_trap_push(); UNGRAB(key, 0); UNGRAB(key, ScrollLockMask); UNGRAB(key, NumLockMask); UNGRAB(key, CapsLockMask); UNGRAB(key, ScrollLockMask | NumLockMask); UNGRAB(key, ScrollLockMask | CapsLockMask); UNGRAB(key, CapsLockMask | NumLockMask); UNGRAB(key, ScrollLockMask | CapsLockMask | NumLockMask); gdk_flush(); return gdk_error_trap_pop() == Success; }
int sexp_read(IOHandle *h, sexp_t **result_ptr) { cmsg_bytes_t buf; sexp_t *stack = NULL; /* held */ sexp_t *hint = NULL; /* held */ sexp_t *body = NULL; /* held */ sexp_t *accumulator = NULL; /* not held */ while (1) { READ1; switch (buf.bytes[0]) { case '[': { iohandle_drain(h, 1); hint = INCREF(read_simple_string(h, EMPTY_BYTES)); if (hint == NULL) goto error; READ1; if (buf.bytes[0] != ']') { h->error_kind = SEXP_ERROR_SYNTAX; goto error; } iohandle_drain(h, 1); skip_whitespace_in_display_hint: READ1; if (isspace(buf.bytes[0])) { iohandle_drain(h, 1); goto skip_whitespace_in_display_hint; } body = INCREF(read_simple_string(h, EMPTY_BYTES)); if (body == NULL) goto error; accumulator = sexp_display_hint(hint, body); DECREF(hint, sexp_destructor); /* these could be UNGRABs */ DECREF(body, sexp_destructor); break; } case '(': iohandle_drain(h, 1); stack = sexp_push(stack, sexp_cons(NULL, NULL)); continue; case ')': { sexp_t *current; if (stack == NULL) { h->error_kind = SEXP_ERROR_SYNTAX; goto error; } stack = sexp_pop(stack, ¤t); INCREF(current); iohandle_drain(h, 1); accumulator = INCREF(sexp_head(current)); DECREF(current, sexp_destructor); UNGRAB(accumulator); break; } default: if (isspace(buf.bytes[0])) { iohandle_drain(h, 1); continue; } buf.len = 1; /* needed to avoid reading too much in read_simple_string */ accumulator = read_simple_string(h, buf); if (accumulator == NULL) goto error; break; } if (stack == NULL) { *result_ptr = accumulator; return 1; } else { sexp_t *current = sexp_head(stack); /* not held */ sexp_t *cell = sexp_cons(accumulator, NULL); if (sexp_tail(current) == NULL) { sexp_sethead(current, cell); } else { sexp_settail(sexp_tail(current), cell); } sexp_settail(current, cell); } } error: DECREF(stack, sexp_destructor); DECREF(hint, sexp_destructor); DECREF(body, sexp_destructor); return 0; }