/* Generates a region containing free space (here the * active window counts as free space). The region argument * is the start-region (ie: the output dev). */ static Region smartputEmptyRegion (CompWindow *window, Region region) { CompScreen *s = window->screen; CompWindow *w; Region newRegion, tmpRegion; XRectangle tmpRect; newRegion = XCreateRegion (); if (!newRegion) return NULL; tmpRegion = XCreateRegion (); if (!tmpRegion) { XDestroyRegion (newRegion); return NULL; } XUnionRegion (region, newRegion, newRegion); for (w = s->windows; w; w = w->next) { EMPTY_REGION (tmpRegion); if (w->id == window->id) continue; if (w->invisible || w->hidden || w->minimized) continue; if (w->wmType & CompWindowTypeDesktopMask) continue; if (w->wmType & CompWindowTypeDockMask) { if (w->struts) { XUnionRectWithRegion (&w->struts->left, tmpRegion, tmpRegion); XUnionRectWithRegion (&w->struts->right, tmpRegion, tmpRegion); XUnionRectWithRegion (&w->struts->top, tmpRegion, tmpRegion); XUnionRectWithRegion (&w->struts->bottom, tmpRegion, tmpRegion); XSubtractRegion (newRegion, tmpRegion, newRegion); } continue; } tmpRect.x = w->serverX - w->input.left; tmpRect.y = w->serverY - w->input.top; tmpRect.width = w->serverWidth + w->input.right + w->input.left; tmpRect.height = w->serverHeight + w->input.top + w->input.bottom; XUnionRectWithRegion (&tmpRect, tmpRegion, tmpRegion); XSubtractRegion (newRegion, tmpRegion, newRegion); } XDestroyRegion (tmpRegion); return newRegion; }
static void minSetShade (CompWindow *w, int shade) { REGION rect; int h = w->attrib.height + w->attrib.border_width * 2; MIN_WINDOW (w); EMPTY_REGION (w->region); rect.rects = &rect.extents; rect.numRects = rect.size = 1; w->height = shade; rect.extents.x1 = 0; rect.extents.y1 = h - shade; rect.extents.x2 = w->width; rect.extents.y2 = h; XIntersectRegion (mw->region, &rect, w->region); XOffsetRegion (w->region, w->attrib.x, w->attrib.y - (h - shade)); w->matrix = w->texture->matrix; w->matrix.x0 -= (w->attrib.x * w->matrix.xx); w->matrix.y0 -= ((w->attrib.y - (h - shade)) * w->matrix.yy); (*w->screen->windowResizeNotify) (w, 0, 0, 0, 0); }
/* * REGION_FrameRgn * Create a region that is a frame around another region. * Expand all rectangles by +/- x and y, then subtract original region. */ BOOL REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y ) { BOOL bRet; MWRGNOBJ *srcObj = (MWRGNOBJ*) GDI_GetObjPtr( hSrc, OBJ_REGION ); if (srcObj->rgn->numRects != 0) { MWRGNOBJ* destObj = (MWRGNOBJ*) GDI_GetObjPtr( hDest, OBJ_REGION ); RECT *pRect, *pEndRect; RECT tempRect; EMPTY_REGION( destObj->rgn ); pEndRect = srcObj->rgn->rects + srcObj->rgn->numRects; for(pRect = srcObj->rgn->rects; pRect < pEndRect; pRect++) { tempRect.left = pRect->left - x; tempRect.top = pRect->top - y; tempRect.right = pRect->right + x; tempRect.bottom = pRect->bottom + y; GdUnionRectWithRegion( &tempRect, destObj->rgn ); } GdSubtractRegion( destObj->rgn, destObj->rgn, srcObj->rgn ); bRet = TRUE; } else bRet = FALSE; return bRet; }
void reg_SetRectRegion(RegionBase *RegionBase, ClipRegion *rgn, INT32 left, INT32 top, INT32 right, INT32 bottom) { if (left != right && top != bottom) { rgn->rects->left = rgn->extents.left = left; rgn->rects->top = rgn->extents.top = top; rgn->rects->right = rgn->extents.right = right; rgn->rects->bottom = rgn->extents.bottom = bottom; rgn->numRects = 1; rgn->type = REGION_SIMPLE; } else EMPTY_REGION(rgn); }
void eventLoop (void) { XEvent event; struct pollfd ufd; int timeDiff; struct timeval tv; Region tmpRegion; CompDisplay *display = compDisplays; CompScreen *s = display->screens; int timeToNextRedraw = 0; CompWindow *move = 0; int px = 0, py = 0; CompTimeout *t; tmpRegion = XCreateRegion (); if (!tmpRegion) { fprintf (stderr, "%s: Couldn't create region\n", programName); return; } ufd.fd = ConnectionNumber (display->display); ufd.events = POLLIN; for (;;) { if (display->dirtyPluginList) updatePlugins (display); if (restartSignal) { execvp (programName, programArgv); exit (1); } while (XPending (display->display)) { XNextEvent (display->display, &event); /* translate root window */ if (testMode) { Window root, child; switch (event.type) { case ButtonPress: if (!move) { px = event.xbutton.x; py = event.xbutton.y; move = findWindowAt (display, event.xbutton.window, px, py); if (move) { XRaiseWindow (display->display, move->id); continue; } } case ButtonRelease: move = 0; root = translateToRootWindow (display, event.xbutton.window); XTranslateCoordinates (display->display, event.xbutton.root, root, event.xbutton.x_root, event.xbutton.y_root, &event.xbutton.x_root, &event.xbutton.y_root, &child); event.xbutton.root = root; break; case KeyPress: case KeyRelease: root = translateToRootWindow (display, event.xkey.window); XTranslateCoordinates (display->display, event.xkey.root, root, event.xkey.x_root, event.xkey.y_root, &event.xkey.x_root, &event.xkey.y_root, &child); event.xkey.root = root; break; case MotionNotify: if (move) { XMoveWindow (display->display, move->id, move->attrib.x + event.xbutton.x - px, move->attrib.y + event.xbutton.y - py); px = event.xbutton.x; py = event.xbutton.y; continue; } root = translateToRootWindow (display, event.xmotion.window); XTranslateCoordinates (display->display, event.xmotion.root, root, event.xmotion.x_root, event.xmotion.y_root, &event.xmotion.x_root, &event.xmotion.y_root, &child); event.xmotion.root = root; default: break; } } /* add virtual modifiers */ switch (event.type) { case ButtonPress: event.xbutton.state |= CompPressMask; event.xbutton.state = realToVirtualModMask (display, event.xbutton.state); break; case ButtonRelease: event.xbutton.state |= CompReleaseMask; event.xbutton.state = realToVirtualModMask (display, event.xbutton.state); break; case KeyPress: event.xkey.state |= CompPressMask; event.xkey.state = realToVirtualModMask (display, event.xkey.state); break; case KeyRelease: event.xkey.state |= CompReleaseMask; event.xkey.state = realToVirtualModMask (display, event.xkey.state); break; case MotionNotify: event.xmotion.state = realToVirtualModMask (display, event.xmotion.state); break; default: break; } (*display->handleEvent) (display, &event); } if (s->allDamaged || REGION_NOT_EMPTY (s->damage)) { if (timeToNextRedraw == 0) { /* wait for X drawing requests to finish glXWaitX (); */ gettimeofday (&tv, 0); timeDiff = TIMEVALDIFF (&tv, &s->lastRedraw); (*s->preparePaintScreen) (s, timeDiff); if (s->allDamaged) { EMPTY_REGION (s->damage); s->allDamaged = 0; (*s->paintScreen) (s, &defaultScreenPaintAttrib, &defaultWindowPaintAttrib, &s->region, PAINT_SCREEN_REGION_MASK | PAINT_SCREEN_FULL_MASK); glXSwapBuffers (s->display->display, s->root); } else { XIntersectRegion (s->damage, &s->region, tmpRegion); EMPTY_REGION (s->damage); if ((*s->paintScreen) (s, &defaultScreenPaintAttrib, &defaultWindowPaintAttrib, tmpRegion, PAINT_SCREEN_REGION_MASK)) { BoxPtr pBox; int nBox, y; glEnable (GL_SCISSOR_TEST); glDrawBuffer (GL_FRONT); pBox = tmpRegion->rects; nBox = tmpRegion->numRects; while (nBox--) { y = s->height - pBox->y2; glBitmap (0, 0, 0, 0, pBox->x1 - s->rasterX, y - s->rasterY, NULL); s->rasterX = pBox->x1; s->rasterY = y; glScissor (pBox->x1, y, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1); glCopyPixels (pBox->x1, y, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1, GL_COLOR); pBox++; } glDrawBuffer (GL_BACK); glDisable (GL_SCISSOR_TEST); glFlush (); } else { (*s->paintScreen) (s, &defaultScreenPaintAttrib, &defaultWindowPaintAttrib, &s->region, PAINT_SCREEN_FULL_MASK); glXSwapBuffers (s->display->display, s->root); } } s->lastRedraw = tv; (*s->donePaintScreen) (s); /* remove destroyed windows */ while (s->pendingDestroys) { CompWindow *w; for (w = s->windows; w; w = w->next) { if (w->destroyed) { addWindowDamage (w); removeWindow (w); break; } } s->pendingDestroys--; } } timeToNextRedraw = getTimeToNextRedraw (s, &s->lastRedraw); if (timeToNextRedraw) timeToNextRedraw = poll (&ufd, 1, timeToNextRedraw); } else { if (timeouts) { if (timeouts->left > 0) poll (&ufd, 1, timeouts->left); gettimeofday (&tv, 0); timeDiff = TIMEVALDIFF (&tv, &lastTimeout); for (t = timeouts; t; t = t->next) t->left -= timeDiff; while (timeouts && timeouts->left <= 0) { t = timeouts; if ((*t->callBack) (t->closure)) { timeouts = t->next; addTimeout (t); } else { timeouts = t->next; free (t); } } s->lastRedraw = lastTimeout = tv; } else { poll (&ufd, 1, 1000); gettimeofday (&s->lastRedraw, 0); } /* just redraw immediately */ timeToNextRedraw = 0; } } }