void qtcShadowCreate(size_t size, const QtcColor *c1, const QtcColor *c2, size_t radius, bool square, QtcPixelByteOrder order, QtcImage **images) { size_t full_size = size + radius; QTC_DEF_LOCAL_BUFF(float, gradient, 128, full_size); for (size_t i = 0;i < radius;i++) { gradient.p[i] = 0; } qtcCreateShadowGradient(gradient.p + radius, size); int aligns[8][2] = { {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, }; for (int i = 0;i < 8;i++) { images[i] = qtcShadowSubImage(full_size, gradient.p, aligns[i][1], aligns[i][0], c1, c2, square, order); } QTC_FREE_LOCAL_BUFF(gradient); }
// Blur QTC_EXPORT void qtcX11BlurTrigger(xcb_window_t wid, bool enable, unsigned prop_num, const uint32_t *props) { QTC_RET_IF_FAIL(wid); xcb_atom_t atom = qtc_x11_kde_net_wm_blur_behind_region; if (enable) { if (qtc_disp) { QTC_DEF_LOCAL_BUFF(unsigned long, xlib_props, 256, prop_num); for (unsigned i = 0;i < prop_num;i++) { xlib_props.p[i] = props[i]; } XChangeProperty(qtc_disp, wid, atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)xlib_props.p, prop_num); QTC_FREE_LOCAL_BUFF(xlib_props); } else { qtcX11ChangeProperty(XCB_PROP_MODE_REPLACE, wid, atom, XCB_ATOM_CARDINAL, 32, prop_num, props); } } else {
QTC_EXPORT bool qtcPopenBuff(const char *file, const char *const argv[], unsigned buff_num, QtcPopenBuff *buffs, int timeout) { if (qtcUnlikely(!buffs || !buff_num)) { return qtcSpawn(file, argv, NULL, NULL); } bool need_poll = false; for (unsigned i = 0;i < buff_num;i++) { QTC_RET_IF_FAIL(buffs[i].orig >= 0, false); QTC_RET_IF_FAIL(!(buffs[i].mode & QTC_POPEN_READ && buffs[i].mode & QTC_POPEN_WRITE), false); if (buffs[i].mode & QTC_POPEN_READ || buffs[i].mode & QTC_POPEN_WRITE) { need_poll = true; } } QTC_DEF_LOCAL_BUFF(QtcPopenFD, fds, 16, buff_num); for (unsigned i = 0;i < buff_num;i++) { fds.p[i].orig = buffs[i].orig; fds.p[i].replace = -1; fds.p[i].mode = buffs[i].mode; } bool res = qtcPopen(file, argv, buff_num, fds.p); if (!res) { QTC_FREE_LOCAL_BUFF(fds); return false; } for (unsigned i = 0;i < buff_num;i++) { buffs[i].orig = fds.p[i].replace; if (fds.p[i].replace >= 0) { qtcFDSetNonBlock(fds.p[i].replace, true); qtcFDSetCloexec(fds.p[i].replace, true); } } QTC_FREE_LOCAL_BUFF(fds); if (!need_poll) { return true; } QTC_DEF_LOCAL_BUFF(struct pollfd, poll_fds, 16, buff_num); QTC_DEF_LOCAL_BUFF(int, indexes, 16, buff_num); unsigned poll_fd_num = 0; for (unsigned i = 0;i < buff_num;i++) { if (!(buffs[i].mode & (QTC_POPEN_READ | QTC_POPEN_WRITE))) { close(buffs[i].orig); continue; } indexes.p[poll_fd_num] = i; struct pollfd *cur_fd = &poll_fds.p[poll_fd_num]; cur_fd->fd = buffs[i].orig; cur_fd->events = (buffs[i].mode & QTC_POPEN_READ) ? POLLIN : POLLOUT; poll_fd_num++; } uint64_t start_time = qtcGetTime(); int poll_timeout = timeout; while (true) { int ret = poll(poll_fds.p, poll_fd_num, poll_timeout); if (ret == -1) { if (errno == EINTR) { if (!qtcPopenPollCheckTimeout(start_time, timeout, &poll_timeout)) { break; } continue; } break; } else if (ret == 0) { break; } for (unsigned i = 0;i < poll_fd_num;i++) { struct pollfd *cur_fd = &poll_fds.p[i]; if (cur_fd->revents & POLLIN) { if (!qtcPopenReadBuff(&buffs[indexes.p[i]])) { cur_fd->events &= ~POLLIN; } } else if (cur_fd->revents & POLLOUT) { if (!qtcPopenWriteBuff(&buffs[indexes.p[i]])) { cur_fd->events &= ~POLLOUT; } } if (cur_fd->revents & (POLLERR | POLLHUP | POLLNVAL) || !(cur_fd->events & (POLLIN | POLLOUT))) { shutdown(cur_fd->fd, SHUT_RDWR); close(cur_fd->fd); poll_fd_num--; memmove(cur_fd, cur_fd + 1, (poll_fd_num - i) * sizeof(struct pollfd)); memmove(indexes.p + i, indexes.p + i + 1, (poll_fd_num - i) * sizeof(int)); i--; } } if (poll_fd_num <= 0 || !qtcPopenPollCheckTimeout(start_time, timeout, &poll_timeout)) { break; } } for (unsigned i = 0;i < poll_fd_num;i++) { struct pollfd *cur_fd = &poll_fds.p[i]; shutdown(cur_fd->fd, SHUT_RDWR); close(cur_fd->fd); } QTC_FREE_LOCAL_BUFF(indexes); QTC_FREE_LOCAL_BUFF(poll_fds); return true; }