gboolean clientTransientOrModalHasAncestor (Client * c, guint ws) { Client *c2; GList *list; ScreenInfo *screen_info; g_return_val_if_fail (c != NULL, FALSE); TRACE ("entering clientTransientOrModalHasAncestor"); if (!clientIsTransientOrModal (c)) { return FALSE; } screen_info = c->screen_info; for (list = screen_info->windows_stack; list; list = g_list_next (list)) { c2 = (Client *) list->data; if ((c2 != c) && !clientIsTransientOrModal (c2) && clientIsTransientOrModalFor (c, c2) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE) && (c2->win_workspace == ws) && (((ws == screen_info->current_ws) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE)) || !FLAG_TEST (c2->flags, CLIENT_FLAG_ICONIFIED))) { return TRUE; } } return FALSE; }
static unsigned long clientStrutAreaOverlap (int x, int y, int w, int h, Client * c) { unsigned long sigma = 0; if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_STRUT) && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE)) { sigma = overlap (x, y, x + w, y + h, 0, c->struts[STRUTS_LEFT_START_Y], c->struts[STRUTS_LEFT], c->struts[STRUTS_LEFT_END_Y]) + overlap (x, y, x + w, y + h, c->screen_info->width - c->struts[STRUTS_RIGHT], c->struts[STRUTS_RIGHT_START_Y], c->screen_info->width, c->struts[STRUTS_RIGHT_END_Y]) + overlap (x, y, x + w, y + h, c->struts[STRUTS_TOP_START_X], 0, c->struts[STRUTS_TOP_END_X], c->struts[STRUTS_TOP]) + overlap (x, y, x + w, y + h, c->struts[STRUTS_BOTTOM_START_X], c->screen_info->height - c->struts[STRUTS_BOTTOM], c->struts[STRUTS_BOTTOM_END_X], c->screen_info->height); } return sigma; }
static void clientAutoMaximize (Client * c, int full_w, int full_h) { if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN) || !FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER)) { /* * Fullscreen or undecorated windows should not be * automatically maximized... */ return; } if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ) && (frameWidth (c) > full_w)) { TRACE ("The application \"%s\" has requested a window width " "(%u) larger than the actual width available in the workspace (%u), " "the window will be maximized horizontally.", c->name, frameWidth (c), full_w); FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ); } if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT) && (frameHeight (c) > full_h)) { TRACE ("The application \"%s\" has requested a window height " "(%u) larger than the actual height available in the workspace (%u), " "the window will be maximized vertically.", c->name, frameHeight (c), full_h); FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_VERT); } }
static void clientCycleActivate (Client *c) { ScreenInfo *screen_info; DisplayInfo *display_info; Client *focused; guint workspace; if (c == NULL) { return; } screen_info = c->screen_info; display_info = screen_info->display_info; workspace = c->win_workspace; focused = clientGetFocus (); if ((focused) && (c != focused)) { /* We might be able to avoid this if we are about to switch workspace */ clientAdjustFullscreenLayer (focused, FALSE); } if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_WAS_SHOWN)) { /* We are explicitely activating a window that was shown before show-desktop */ clientClearAllShowDesktop (screen_info); } if (workspace != screen_info->current_ws) { workspaceSwitch (screen_info, workspace, c, FALSE, myDisplayGetCurrentTime (display_info)); } clientCycleFocusAndRaise (c); }
void clientInitFocusFlag (Client * c) { ScreenInfo *screen_info; Client *c2; GList *list; guint workspace; g_return_if_fail (c != NULL); TRACE ("client \"%s\" (0x%lx)", c->name, c->window); if (!clientAcceptFocus (c) || (c->type & WINDOW_TYPE_DONT_FOCUS)) { return; } screen_info = c->screen_info; workspace = c->win_workspace; for (list = screen_info->windows_stack; list; list = g_list_next (list)) { c2 = (Client *) list->data; if ((c2->win_workspace == workspace) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_FOCUS)) { FLAG_UNSET (c2->xfwm_flags, XFWM_FLAG_FOCUS); } } FLAG_SET (c->xfwm_flags, XFWM_FLAG_FOCUS); }
void clientUpdateFocus (ScreenInfo *screen_info, Client * c, unsigned short flags) { Client *c2; gboolean restacked; TRACE ("entering"); c2 = ((client_focus != c) ? client_focus : NULL); if ((c) && !clientAcceptFocus (c)) { TRACE ("SKIP_FOCUS set for client \"%s\" (0x%lx)", c->name, c->window); pending_focus = NULL; return; } if ((c) && (c == client_focus) && !(flags & FOCUS_FORCE)) { TRACE ("client \"%s\" (0x%lx) is already focused, ignoring request", c->name, c->window); pending_focus = NULL; return; } client_focus = c; if (c2) { clientSetNetState (c2); clientAdjustFullscreenLayer (c2, FALSE); frameQueueDraw (c2, FALSE); clientUpdateOpacity (c2); } if (c) { user_focus = c; clientInstallColormaps (c); if (flags & FOCUS_SORT) { clientSortRing(c); } if (FLAG_TEST(c->flags, CLIENT_FLAG_DEMANDS_ATTENTION)) { TRACE ("un-setting WM_STATE_DEMANDS_ATTENTION flag on \"%s\" (0x%lx)", c->name, c->window); FLAG_UNSET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION); } clientSetNetState (c); restacked = clientAdjustFullscreenLayer (c, TRUE); if (!restacked && screen_info->params->click_to_focus) { clientRaise (c, None); clientSetLastRaise (c); } frameQueueDraw (c, FALSE); clientUpdateOpacity (c); } clientSetNetActiveWindow (screen_info, c, 0); pending_focus = NULL; }
gboolean clientIsModalForGroup (Client * c) { g_return_val_if_fail (c != NULL, FALSE); TRACE ("entering clientIsModalForGroup"); return (FLAG_TEST (c->flags, CLIENT_FLAG_STATE_MODAL) && (c->type & WINDOW_REGULAR_FOCUSABLE) && !clientIsTransient(c) && (c->group_leader != None)); }
error_t ibmPc_rtc_initialize(void) { error_t ret; ubit8 status1; ret = ibmPc_rtccmos_initialize(); if (ret != ERROR_SUCCESS) { return ret; }; rtccmos::lock(); rtccmos::writeAddressRegister(RTC_REG_STATUS1); status1 = rtccmos::readDataRegister(); // Clear all IRQs. FLAG_UNSET(status1, RTC_STATUS1_FLAGS_PERIODIC_IRQ_ENABLED | RTC_STATUS1_FLAGS_ALARM_IRQ_ENABLED | RTC_STATUS1_FLAGS_UPDATEEND_IRQ_ENABLED); rtccmos::writeAddressRegister(RTC_REG_STATUS1); rtccmos::writeDataRegister(status1); rtccmos::resetAddressRegister(); rtccmos::unlock(); rtccmos24HourTime = FLAG_TEST(status1, RTC_STATUS1_FLAGS_TIME_FORMAT_24HRS); if (!rtccmos24HourTime) { printf(ERROR RTCCMOS"Chip reports 12 hour format time.\n"); }; rtccmosBcdDateTime = !FLAG_TEST(status1, RTC_STATUS1_FLAGS_DATETIME_FORMAT_BIN); if (!rtccmosBcdDateTime) { printf(WARNING RTCCMOS"Date/Time is not in BCD. Possibly " "unstable or non-compliant chip.\n"); }; return ERROR_SUCCESS; }
gboolean clientAcceptFocus (Client * c) { g_return_val_if_fail (c != NULL, FALSE); TRACE ("client \"%s\" (0x%lx)", c->name, c->window); /* Modal dialogs *always* accept focus */ if (FLAG_TEST(c->flags, CLIENT_FLAG_STATE_MODAL)) { return TRUE; } if ((c->screen_info->params->focus_hint) && !FLAG_TEST (c->wm_flags, WM_FLAG_INPUT | WM_FLAG_TAKEFOCUS)) { return FALSE; } return TRUE; }
gboolean clientSelectMask (Client * c, Client *other, guint mask, guint type) { g_return_val_if_fail (c != NULL, FALSE); TRACE ("client \"%s\" (0x%lx)", c->name, c->window); if ((mask & SEARCH_SAME_APPLICATION) && !clientSameApplication (c, other)) { return FALSE; } if ((mask & SEARCH_DIFFERENT_APPLICATION) && clientSameApplication (c, other)) { return FALSE; } if (!(mask & SEARCH_INCLUDE_SKIP_FOCUS) && !clientAcceptFocus (c)) { return FALSE; } if (!(mask & SEARCH_INCLUDE_HIDDEN) && FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED)) { return FALSE; } if (!(mask & SEARCH_INCLUDE_ALL_WORKSPACES) && (c->win_workspace != c->screen_info->current_ws)) { return FALSE; } if (!(mask & SEARCH_INCLUDE_SKIP_PAGER) && FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_PAGER)) { return FALSE; } if (!(mask & SEARCH_INCLUDE_SKIP_TASKBAR) && FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_TASKBAR)) { return FALSE; } if (c->type & type) { return TRUE; } return (c->type & type); }
gboolean clientIsModal (Client * c) { g_return_val_if_fail (c != NULL, FALSE); TRACE ("entering clientIsModal"); /* If the WM_TRANSIENT_FOR hint is set to another toplevel window, the dialog is modal for that window; if WM_TRANSIENT_FOR is not set or set to the root window the dialog is modal for its window group. */ return (FLAG_TEST (c->flags, CLIENT_FLAG_STATE_MODAL) && (c->type & WINDOW_REGULAR_FOCUSABLE) && (((c->transient_for != c->screen_info->xroot) && (c->transient_for != None) && (c->transient_for != c->window)) || ((c->group_leader != None) && (c->group_leader != c->window)))); }
void gc_mark( VALUE value ) { if( !IS_PTR_VALUE(value) ) { return; } if( FLAG_TEST( value, FLAG_GC_MARK ) ) { return; } if( RANY(value)->as.free.flags == 0 ) { return; } FLAG_SET( value, FLAG_GC_MARK ); gc_mark( R_BASIC(value)->klass ); switch(VALUE_TYPE(value)) { case TYPE_STRING: break; case TYPE_ARRAY: { int i; for( i=0; i< R_ARRAY(value)->len; ++i ) { gc_mark( R_ARRAY(value)->ptr[i] ); } break; } case TYPE_CLASS: gc_mark( (VALUE)(R_CLASS(value)->super) ); var_tbl_mark( R_CLASS(value)->ival_tbl ); var_tbl_mark( R_CLASS(value)->method_tbl ); break; case TYPE_OBJECT: gc_mark( (VALUE)(R_BASIC(value)->klass) ); var_tbl_mark( R_OBJECT(value)->ival_tbl ); break; case TYPE_METHOD: break; default: rabbit_bug("(GC MARK)未対応型のオブジェクトが送られてきました(type %d)", VALUE_TYPE(value) ); } }
gboolean clientIsModalFor (Client * c1, Client * c2) { g_return_val_if_fail (c1 != NULL, FALSE); g_return_val_if_fail (c2 != NULL, FALSE); TRACE ("entering clientIsModalFor"); if (FLAG_TEST (c1->flags, CLIENT_FLAG_STATE_MODAL) && (c1->type & WINDOW_REGULAR_FOCUSABLE) && (c1->serial >= c2->serial)) { /* * We used to consider all windows of the same group here * (ie. "clientSameGroup (c1, c2)") but that seems too * wide so we restric modality to transient relationship * for now. */ return (clientIsTransientFor (c1, c2)); } return FALSE; }
void *HardwareIdList::getItem(sarch_t id) { uarch_t rwFlags; void *ret=NULL; arr.lock.readAcquire(&rwFlags); if (id > arr.rsrc.maxIndex || id < arr.rsrc.firstValidIndex) { arr.lock.readRelease(rwFlags); return NULL; }; if (FLAG_TEST(arr.rsrc.arr[id].flags, HWIDLIST_FLAGS_INDEX_VALID)) { ret = arr.rsrc.arr[id].item; }; arr.lock.readRelease(rwFlags); return ret; }
static ClientPair clientGetTopMostFocusable (ScreenInfo *screen_info, guint layer, GList * exclude_list) { ClientPair top_client; Client *c; GList *list; TRACE ("entering"); top_client.prefered = top_client.highest = NULL; for (list = screen_info->windows_stack; list; list = g_list_next (list)) { c = (Client *) list->data; TRACE ("stack window \"%s\" (0x%lx), layer %i", c->name, c->window, (int) c->win_layer); if (!clientAcceptFocus (c) || (c->type & WINDOW_TYPE_DONT_FOCUS)) { continue; } if (!g_list_find (exclude_list, (gconstpointer) c)) { if (c->win_layer > layer) { break; } else if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE)) { if (clientSelectMask (c, NULL, 0, WINDOW_REGULAR_FOCUSABLE)) { top_client.prefered = c; } top_client.highest = c; } } } return top_client; }
error_t HardwareIdList::findFreeIndex(uarch_t *id) { uarch_t rwFlags; arr.lock.readAcquire(&rwFlags); for (uarch_t i=0; i<static_cast<uarch_t>( arr.rsrc.maxAllocatedIndex + 1 ); i++) { if (!FLAG_TEST( arr.rsrc.arr[i].flags, HWIDLIST_FLAGS_INDEX_VALID)) { arr.lock.readRelease(rwFlags); *id = i; return ERROR_SUCCESS; }; }; arr.lock.readRelease(rwFlags); return ERROR_GENERAL; }
/* clientConstrainPos() is used when moving windows to ensure that the window stays accessible to the user Returns the position in which the window was constrained. CLIENT_CONSTRAINED_TOP = 1<<0 CLIENT_CONSTRAINED_BOTTOM = 1<<1 CLIENT_CONSTRAINED_LEFT = 1<<2 CLIENT_CONSTRAINED_RIGHT = 1<<3 */ unsigned int clientConstrainPos (Client * c, gboolean show_full) { Client *c2; ScreenInfo *screen_info; guint i; gint cx, cy, disp_x, disp_y, disp_max_x, disp_max_y; gint frame_height, frame_width, frame_top, frame_left; gint frame_x, frame_y, frame_visible; gint screen_width, screen_height; guint ret; GdkRectangle rect; gint min_visible; g_return_val_if_fail (c != NULL, 0); TRACE ("entering clientConstrainPos %s", show_full ? "(with show full)" : "(w/out show full)"); TRACE ("client \"%s\" (0x%lx)", c->name, c->window); /* We use a bunch of local vars to reduce the overhead of calling other functions all the time */ frame_x = frameX (c); frame_y = frameY (c); frame_height = frameHeight (c); frame_width = frameWidth (c); frame_top = frameTop (c); frame_left = frameLeft (c); frame_visible = (frame_top ? frame_top : frame_height); min_visible = MAX (frame_top, CLIENT_MIN_VISIBLE); ret = 0; cx = frame_x + (frame_width / 2); cy = frame_y + (frame_height / 2); screen_info = c->screen_info; myScreenFindMonitorAtPoint (screen_info, cx, cy, &rect); screen_width = screen_info->width; screen_height = screen_info->height; disp_x = rect.x; disp_y = rect.y; disp_max_x = rect.x + rect.width; disp_max_y = rect.y + rect.height; if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN)) { TRACE ("ignoring constrained for client \"%s\" (0x%lx)", c->name, c->window); return 0; } if (show_full) { /* Struts and other partial struts */ for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++) { if (FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE) && (c2 != c)) { /* Right */ if (segment_overlap (frame_y, frame_y + frame_height, c2->struts[STRUTS_RIGHT_START_Y], c2->struts[STRUTS_RIGHT_END_Y])) { if (segment_overlap (frame_x, frame_x + frame_width, screen_width - c2->struts[STRUTS_RIGHT], screen_width)) { c->x = screen_width - c2->struts[STRUTS_RIGHT] - frame_width + frame_left; frame_x = frameX (c); ret |= CLIENT_CONSTRAINED_RIGHT; } } /* Bottom */ if (segment_overlap (frame_x, frame_x + frame_width, c2->struts[STRUTS_BOTTOM_START_X], c2->struts[STRUTS_BOTTOM_END_X])) { if (segment_overlap (frame_y, frame_y + frame_height, screen_height - c2->struts[STRUTS_BOTTOM], screen_height)) { c->y = screen_height - c2->struts[STRUTS_BOTTOM] - frame_height + frame_top; frame_y = frameY (c); ret |= CLIENT_CONSTRAINED_BOTTOM; } } } } if (frame_x + frame_width >= disp_max_x) { c->x = disp_max_x - frame_width + frame_left; frame_x = frameX (c); ret |= CLIENT_CONSTRAINED_RIGHT; } if (frame_x <= disp_x) { c->x = disp_x + frame_left; frame_x = frameX (c); ret |= CLIENT_CONSTRAINED_LEFT; } if (frame_y + frame_height >= disp_max_y) { c->y = disp_max_y - frame_height + frame_top; frame_y = frameY (c); ret |= CLIENT_CONSTRAINED_BOTTOM; } if (frame_y <= disp_y) { c->y = disp_y + frame_top; frame_y = frameY (c); ret |= CLIENT_CONSTRAINED_TOP; } for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++) { if (FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE) && (c2 != c)) { /* Left */ if (segment_overlap (frame_y, frame_y + frame_height, c2->struts[STRUTS_LEFT_START_Y], c2->struts[STRUTS_LEFT_END_Y])) { if (segment_overlap (frame_x, frame_x + frame_width, 0, c2->struts[STRUTS_LEFT])) { c->x = c2->struts[STRUTS_LEFT] + frame_left; frame_x = frameX (c); ret |= CLIENT_CONSTRAINED_LEFT; } } /* Top */ if (segment_overlap (frame_x, frame_x + frame_width, c2->struts[STRUTS_TOP_START_X], c2->struts[STRUTS_TOP_END_X])) { if (segment_overlap (frame_y, frame_y + frame_height, 0, c2->struts[STRUTS_TOP])) { c->y = c2->struts[STRUTS_TOP] + frame_top; frame_y = frameY (c); ret |= CLIENT_CONSTRAINED_TOP; } } } } } else { if (frame_x + frame_width <= disp_x + min_visible) { c->x = disp_x + min_visible - frame_width + frame_left; frame_x = frameX (c); ret |= CLIENT_CONSTRAINED_LEFT; } if (frame_x + min_visible >= disp_max_x) { c->x = disp_max_x - min_visible + frame_left; frame_x = frameX (c); ret |= CLIENT_CONSTRAINED_RIGHT; } if (frame_y + frame_height <= disp_y + min_visible) { c->y = disp_y + min_visible - frame_height + frame_top; frame_y = frameY (c); ret |= CLIENT_CONSTRAINED_TOP; } if (frame_y + min_visible >= disp_max_y) { c->y = disp_max_y - min_visible + frame_top; frame_y = frameY (c); ret |= CLIENT_CONSTRAINED_BOTTOM; } if ((frame_y <= disp_y) && (frame_y >= disp_y - frame_top)) { c->y = disp_y + frame_top; frame_y = frameY (c); ret |= CLIENT_CONSTRAINED_TOP; } /* Struts and other partial struts */ for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++) { if (FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE) && (c2 != c)) { /* Right */ if (segment_overlap (frame_y, frame_y + frame_height, c2->struts[STRUTS_RIGHT_START_Y], c2->struts[STRUTS_RIGHT_END_Y])) { if (frame_x >= screen_width - c2->struts[STRUTS_RIGHT] - min_visible) { c->x = screen_width - c2->struts[STRUTS_RIGHT] - min_visible + frame_left; frame_x = frameX (c); ret |= CLIENT_CONSTRAINED_RIGHT; } } /* Left */ if (segment_overlap (frame_y, frame_y + frame_height, c2->struts[STRUTS_LEFT_START_Y], c2->struts[STRUTS_LEFT_END_Y])) { if (frame_x + frame_width <= c2->struts[STRUTS_LEFT] + min_visible) { c->x = c2->struts[STRUTS_LEFT] + min_visible - frame_width + frame_left; frame_x = frameX (c); ret |= CLIENT_CONSTRAINED_LEFT; } } /* Bottom */ if (segment_overlap (frame_x, frame_x + frame_width, c2->struts[STRUTS_BOTTOM_START_X], c2->struts[STRUTS_BOTTOM_END_X])) { if (frame_y >= screen_height - c2->struts[STRUTS_BOTTOM] - min_visible) { c->y = screen_height - c2->struts[STRUTS_BOTTOM] - min_visible + frame_top; frame_y = frameY (c); ret |= CLIENT_CONSTRAINED_BOTTOM; } } /* Top */ if (segment_overlap (frame_x, frame_x + frame_width, c2->struts[STRUTS_TOP_START_X], c2->struts[STRUTS_TOP_END_X])) { if (segment_overlap (frame_y, frame_y + frame_visible, 0, c2->struts[STRUTS_TOP])) { c->y = c2->struts[STRUTS_TOP] + frame_top; frame_y = frameY (c); ret |= CLIENT_CONSTRAINED_TOP; } if (frame_y + frame_height <= c2->struts[STRUTS_TOP] + min_visible) { c->y = c2->struts[STRUTS_TOP] + min_visible - frame_height + frame_top; frame_y = frameY (c); ret |= CLIENT_CONSTRAINED_TOP; } } } } } return ret; }
status_t I8254Pit::isr(ZkcmDeviceBase *self, ubit32 flags) { (void) flags; ubit32 devFlags; sZkcmTimerEvent *irqEvent; I8254Pit *device; error_t err; modeE mode; /** EXPLANATION: * 1. Check to make sure that this is not a "disabling" IRQ which is * meant to cause the i8254 to stop sending in IRQs. If it is the * disabling IRQ, unregister the ISR and exit. * 2. If this is not a disabling IRQ, queue an event and exit. **/ device = static_cast<I8254Pit *>( self ); device->state.lock.acquire(); devFlags = device->state.rsrc.flags; mode = device->state.rsrc.mode; // If this is the "disabling" final cleanup IRQ: if (device->i8254State.irqState == sI8254State::DISABLING) { device->i8254State.isrRegistered = 0; device->i8254State.irqState = sI8254State::DISABLED; device->state.lock.release(); // Part of the IBM-PC Symmetric IO mode switch. if (device->i8254State.smpModeSwitchInProgress) { // Release the lock and exit. taskTrib.unblock( device->i8254State.smpModeSwitchThread); }; return ZKCM_ISR_SUCCESS_AND_RETIRE_ME; }; // Small state machine cleanup for oneshot mode: unset the ENABLED flag. if (mode == ONESHOT) { FLAG_UNSET( device->state.rsrc.flags, ZKCM_TIMERDEV_STATE_FLAGS_ENABLED | ZKCM_TIMERDEV_STATE_FLAGS_SOFT_ENABLED); }; device->state.lock.release(); // Don't claim the IRQ if the timer hadn't been enabled. if (!FLAG_TEST(devFlags, ZKCM_TIMERDEV_STATE_FLAGS_ENABLED)) { return ZKCM_ISR_NOT_MY_IRQ; }; device->sendEoi(); // Invoke the system clock update routine if installed on this device. if (device->clockRoutine != NULL) { // Accesses state without the lock. Safe. (*device->clockRoutine)( (mode == ONESHOT) ? device->state.rsrc.currentTimeout.nseconds : device->state.rsrc.currentInterval.nseconds); }; // Create an event. if (!FLAG_TEST(devFlags, ZKCM_TIMERDEV_STATE_FLAGS_SOFT_ENABLED)) { return ZKCM_ISR_SUCCESS; }; irqEvent = device->allocateIrqEvent(); // Note well, this is faultable memory being allocated. if (irqEvent == NULL) { printf(WARNING i8254"isr: Couldn't allocate IRQ event.\n"); // FIXME: I don't like this return value. return ZKCM_ISR_SUCCESS; }; // Fill out the event and queue it. irqEvent->device = device; device->getLatchState( &irqEvent->latchedStream); timerTrib.getCurrentDateTime(&irqEvent->irqStamp); err = device->irqEventQueue.addItem(irqEvent); if (err != ERROR_SUCCESS) { device->freeIrqEvent(irqEvent); printf(WARNING i8254"isr: Failed to queue IRQ event; " "err %s.\n", strerror(err)); }; return ZKCM_ISR_SUCCESS; }
void clientSetFocus (ScreenInfo *screen_info, Client *c, guint32 timestamp, unsigned short flags) { Client *c2; TRACE ("entering"); c2 = NULL; if ((c) && !(flags & FOCUS_IGNORE_MODAL)) { c2 = clientGetModalFor (c); if (c2) { c = c2; } } c2 = ((client_focus != c) ? client_focus : NULL); if ((c) && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE)) { TRACE ("setting focus to client \"%s\" (0x%lx) with timestamp %u", c->name, c->window, (unsigned int) timestamp); user_focus = c; if (FLAG_TEST(c->flags, CLIENT_FLAG_DEMANDS_ATTENTION)) { TRACE ("un-setting WM_STATE_DEMANDS_ATTENTION flag on \"%s\" (0x%lx)", c->name, c->window); FLAG_UNSET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION); clientSetNetState (c); } if ((c == client_focus) && !(flags & FOCUS_FORCE)) { TRACE ("client \"%s\" (0x%lx) is already focused, ignoring request", c->name, c->window); return; } if (!clientAcceptFocus (c)) { TRACE ("SKIP_FOCUS set for client \"%s\" (0x%lx)", c->name, c->window); return; } if (FLAG_TEST (c->wm_flags, WM_FLAG_INPUT) || !(screen_info->params->focus_hint)) { pending_focus = c; /* * When shaded, the client window is unmapped, so it can not be focused. * Instead, we focus the frame that is still mapped. */ if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED)) { XSetInputFocus (myScreenGetXDisplay (screen_info), c->frame, RevertToPointerRoot, timestamp); } else { XSetInputFocus (myScreenGetXDisplay (screen_info), c->window, RevertToPointerRoot, timestamp); } } else if (flags & FOCUS_TRANSITION) { /* * If we are relying only on the client application to take focus, we need to set the focus * explicitely on our own fallback window otherwise there is a race condition between the * application and the window manager. If the application does not take focus before the * the previously focused window is unmapped (when iconifying or closing for example), the focus * will be reverted to the root window and focus transition will fail. */ clientFocusNone (screen_info, c2, timestamp); } if (FLAG_TEST(c->wm_flags, WM_FLAG_TAKEFOCUS)) { pending_focus = c; sendClientMessage (c->screen_info, c->window, WM_TAKE_FOCUS, timestamp); } } else { TRACE ("setting focus to none"); client_focus = NULL; clientFocusNone (screen_info, c2, timestamp); clientClearDelayedFocus (); } }
sZkcmSmpMap *ZkcmCpuDetectionMod::getSmpMap(void) { x86Mp::sCpuConfig *mpCpu; void *handle, *handle2, *context; uarch_t pos=0, nEntries, i; sZkcmSmpMap *ret; acpi::sRsdt *rsdt; acpiR::sMadt *madt; acpiR::madt::sCpu *madtCpu; /** NOTES: * This function will return a structure describing all CPUs at boot, * regardless of NUMA bank membership, and regardless of whether or not * that CPU is enabled, bad, or was already described in the NUMA Map. * * This SMP map is used to generate shared bank CPUs (CPUs which were * not mentioned in the NUMA Map, yet are mentioned here), and to tell * the kernel which CPUs are bad, and in an "un-enabled", or unusable * state, though not bad. * * EXPLANATION: * This function will use the Intel x86 MP Specification structures to * enumerate CPUs, and build the SMP map, combining it with the info * returned from the NUMA map. * * This function depends on the kernel libx86mp. **/ // First try using ACPI. Trust ACPI over MP tables. acpi::findRsdp(); // acpi::initializeCache(); if (acpi::findRsdp() != ERROR_SUCCESS) { printf(NOTICE SMPINFO"getSmpMap: No ACPI. Trying MP.\n"); goto tryMpTables; }; if (!acpi::testForRsdt()) { printf(WARNING SMPINFO"getSmpMap: ACPI, but no RSDT.\n"); if (acpi::testForXsdt()) { printf(WARNING SMPINFO"getSmpMap: XSDT found. " "Consider using 64-bit build for XSDT.\n"); } goto tryMpTables; }; if (acpi::mapRsdt() != ERROR_SUCCESS) { printf(NOTICE SMPINFO"getSmpMap: ACPI: Failed to map RSDT." "\n"); goto tryMpTables; }; // Now look for an MADT. rsdt = acpi::getRsdt(); context = handle = NULL; nEntries = 0; madt = acpiRsdt::getNextMadt(rsdt, &context, &handle); while (madt != NULL) { handle2 = NULL; for (madtCpu = acpiR::madt::getNextCpuEntry(madt, &handle2); madtCpu != NULL; madtCpu = acpiR::madt::getNextCpuEntry(madt, &handle2)) { if (FLAG_TEST( madtCpu->flags, ACPI_MADT_CPU_FLAGS_ENABLED)) { nEntries++; }; }; acpiRsdt::destroySdt((acpi::sSdt *)madt); madt = acpiRsdt::getNextMadt(rsdt, &context, &handle); }; printf(NOTICE SMPINFO"getSmpMap: ACPI: %d valid CPU entries.\n", nEntries); ret = new sZkcmSmpMap; if (ret == NULL) { printf(ERROR SMPINFO"getSmpMap: Failed to alloc SMP map.\n"); return NULL; }; ret->entries = new sZkcmMemMapEntry[nEntries]; if (ret->entries == NULL) { delete ret; printf(ERROR SMPINFO"getSmpMap: Failed to alloc SMP map " "entries.\n"); return NULL; }; i=0; context = handle = NULL; madt = acpiRsdt::getNextMadt(rsdt, &context, &handle); while (madt != NULL) { handle2 = NULL; for (madtCpu = acpiR::madt::getNextCpuEntry(madt, &handle2); madtCpu != NULL; madtCpu = acpiR::madt::getNextCpuEntry(madt, &handle2)) { if (FLAG_TEST( madtCpu->flags, ACPI_MADT_CPU_FLAGS_ENABLED)) { ret->entries[i].cpuId = madtCpu->lapicId; ret->entries[i].cpuAcpiId = madtCpu->acpiLapicId; ret->entries[i].flags = 0; i++; continue; }; printf(NOTICE SMPINFO"getSmpMap: ACPI: Skipping " "un-enabled CPU %d, ACPI ID %d.\n", madtCpu->lapicId, madtCpu->acpiLapicId); }; acpiRsdt::destroySdt((acpi::sSdt *)madt); madt = acpiRsdt::getNextMadt(rsdt, &context, &handle); }; ret->nEntries = i; return ret; tryMpTables: printf(NOTICE SMPINFO"getSmpMap: Falling back to MP tables.\n"); x86Mp::initializeCache(); if (!x86Mp::mpFpFound()) { if (x86Mp::findMpFp() == NULL) { printf(NOTICE SMPINFO"getSmpMap: No MP tables.\n"); return NULL; }; if (x86Mp::mapMpConfigTable() == NULL) { printf(ERROR SMPINFO"getSmpMap: Unable to map MP " "Config tables.\n"); return NULL; }; // Parse x86 MP table info and discover how many CPUs there are. nEntries = 0; handle = NULL; mpCpu = x86Mp::getNextCpuEntry(&pos, &handle); for (; mpCpu != NULL; mpCpu = x86Mp::getNextCpuEntry(&pos, &handle)) { if (FLAG_TEST( mpCpu->flags, x86_MPCFG_CPU_FLAGS_ENABLED)) { nEntries++; }; }; printf(NOTICE SMPINFO"getSmpMap: %d valid CPU entries in MP " "config tables.\n", nEntries); ret = new sZkcmSmpMap; if (ret == NULL) { printf(ERROR SMPINFO"getSmpMap: Failed to alloc SMP " "Map.\n"); return NULL; }; ret->entries = new sZkcmMemMapEntry[nEntries]; if (ret->entries == NULL) { printf(ERROR SMPINFO"getSmpMap: Failed to alloc SMP " "map entries.\n"); delete ret; return NULL; }; // Iterate one more time and fill in SMP map. pos = 0; handle = NULL; mpCpu = x86Mp::getNextCpuEntry(&pos, &handle); for (i=0; mpCpu != NULL; mpCpu = x86Mp::getNextCpuEntry(&pos, &handle)) { if (!FLAG_TEST( mpCpu->flags, x86_MPCFG_CPU_FLAGS_ENABLED)) { FLAG_SET( ret->entries[i].flags, ZKCM_SMPMAP_FLAGS_BADCPU); ret->entries[i].cpuId = mpCpu->lapicId; if (FLAG_TEST( mpCpu->flags, x86_MPCFG_CPU_FLAGS_BSP)) { FLAG_SET( ret->entries[i].flags, ZKCM_SMPMAP_FLAGS_BSP); }; continue; }; printf(NOTICE SMPINFO"getSmpMap: Skipping un-enabled" " CPU %d in MP tables.\n", mpCpu->lapicId); }; ret->nEntries = i; return ret; }; return NULL; }
static sZkcmNumaMap *ibmPc_cm_rGnm(void) { sZkcmNumaMap *ret; acpi::sRsdt *rsdt; acpiR::sSrat *srat; acpiR::srat::sCpu *cpuEntry; void *handle, *handle2, *context; ubit32 nEntries=0, i=0; // Caller has determined that there is an RSDT present on the chipset. if (acpi::mapRsdt() != ERROR_SUCCESS) { printf(NOTICE CPUMOD"getNumaMap(): Failed to map in the " "RSDT.\n"); return NULL; }; rsdt = acpi::getRsdt(); // Get the SRAT (all if multiple). context = handle = NULL; srat = acpiRsdt::getNextSrat(rsdt, &context, &handle); while (srat != NULL) { // For each SRAT (if multiple), get the LAPIC entries. handle2 = NULL; cpuEntry = acpiR::srat::getNextCpuEntry(srat, &handle2); for (; cpuEntry != NULL; cpuEntry = acpiR::srat::getNextCpuEntry(srat, &handle2)) { // Count the number of entries there are in all. nEntries++; }; acpiRsdt::destroySdt((acpi::sSdt *)srat); srat = acpiRsdt::getNextSrat(rsdt, &context, &handle); }; printf(NOTICE CPUMOD"getNumaMap(): %d LAPIC SRAT entries.\n", nEntries); // If there are no NUMA CPUs, return. if (nEntries == 0) { return NULL; }; // Now we know how many entries exist. Allocate map and reparse. ret = new sZkcmNumaMap; if (ret == NULL) { printf(ERROR CPUMOD"getNumaMap(): Failed to allocate room " "for CPU NUMA map, or 0 entries found.\n"); return NULL; }; ret->cpuEntries = new sNumaCpuMapEntry[nEntries]; if (ret->cpuEntries == NULL) { delete ret; printf(ERROR CPUMOD"getNumaMap(): Failed to alloc " "NUMA CPU map entries.\n"); return NULL; }; // Reparse entries and create generic kernel CPU map. context = handle = NULL; srat = acpiRsdt::getNextSrat(rsdt, &context, &handle); while (srat != NULL) { handle2 = NULL; cpuEntry = acpiR::srat::getNextCpuEntry(srat, &handle2); for (; cpuEntry != NULL; cpuEntry = acpiR::srat::getNextCpuEntry(srat, &handle2), i++) { /** FIXME * For this case, we don't know what the correct ACPI * ID is. We'd like to assume of course, that the ACPI * ID is the same as the LAPIC ID. This is often not * the case. * * The most effective solution may be to cross check * the SRAT entries with the MADT entries and try * to determine if the CPU is also in the MADT. Then we * can extract its ACPI ID from there. **/ ret->cpuEntries[i].cpuId = cpuEntry->lapicId; ret->cpuEntries[i].cpuAcpiId = cpuEntry->lapicId; ret->cpuEntries[i].bankId = cpuEntry->domain0 | (cpuEntry->domain1 & 0xFFFFFF00); ret->cpuEntries[i].flags = 0; if (FLAG_TEST( cpuEntry->flags, ACPI_SRAT_CPU_FLAGS_ENABLED)) { FLAG_SET( ret->cpuEntries[i].flags, NUMACPUMAP_FLAGS_ONLINE); }; }; acpiRsdt::destroySdt((acpi::sSdt *)srat); srat = acpiRsdt::getNextSrat(rsdt, &context, &handle); }; ret->nCpuEntries = nEntries; return ret; }
error_t ZkcmCpuDetectionMod::setSmpMode(void) { error_t ret; ubit8 *lowmem; void *srcAddr, *destAddr; uarch_t copySize, cpuFlags; x86Mp::sFloatingPtr *mpFp; ubit8 i8254WasEnabled=0, i8254WasSoftEnabled=0; /** EXPLANATION: * This function will enable Symmetric I/O mode on the IBM-PC chipset. * By extension, it also sets the CMOS warm reset mode and the BIOS * reset vector. * * Everything done here is taken from the MP specification and Intel * manuals, with cross-examination from Linux source just in case. * * Naturally, to access lowmem, we use the chipset's memoryAreas * manager. * * NOTE: * * I don't think you need to enable Symm. I/O mode to use the LAPICs. **/ ret = chipsetMemAreas::mapArea(CHIPSET_MEMAREA_LOWMEM); if (ret != ERROR_SUCCESS) { printf(ERROR CPUMOD"setSmpMode(): Failed to map lowmem.\n"); return ret; }; lowmem = static_cast<ubit8 *>( chipsetMemAreas::getArea(CHIPSET_MEMAREA_LOWMEM) ); // Change the warm reset vector. *reinterpret_cast<uarch_t **>( &lowmem[(0x40 << 4) + 0x67] ) = &__kcpuPowerOnTextStart; // TODO: Set CMOS reset operation to "warm reset". cpuControl::safeDisableInterrupts(&cpuFlags); io::write8(0x70, 0x0F); io::write8(0x71, 0x0A); cpuControl::safeEnableInterrupts(cpuFlags); /* Next, we need to copy the kernel's .__kcpuPowerOn[Text/Data] stuff to * lowmem. Memcpy() ftw... **/ srcAddr = (void *)(((uarch_t)&__kcpuPowerOnTextStart - x8632_IBMPC_POWERON_PADDR_BASE) + ARCH_MEMORY___KLOAD_VADDR_BASE); destAddr = &lowmem[(uarch_t)&__kcpuPowerOnTextStart]; copySize = (uarch_t)&__kcpuPowerOnTextEnd - (uarch_t)&__kcpuPowerOnTextStart; printf(NOTICE CPUMOD"setSmpMode: Copy CPU wakeup code: %p " "to %p; %d B.\n", srcAddr, destAddr, copySize); memcpy(destAddr, srcAddr, copySize); srcAddr = (void *)(((uarch_t)&__kcpuPowerOnDataStart - x8632_IBMPC_POWERON_PADDR_BASE) + ARCH_MEMORY___KLOAD_VADDR_BASE); destAddr = &lowmem[(uarch_t)&__kcpuPowerOnDataStart]; copySize = (uarch_t)&__kcpuPowerOnDataEnd - (uarch_t)&__kcpuPowerOnDataStart; printf(NOTICE CPUMOD"setSmpMode: Copy CPU wakeup data: %p " "to %p; %d B.\n", srcAddr, destAddr, copySize); memcpy(destAddr, srcAddr, copySize); x86IoApic::initializeCache(); if (!x86IoApic::ioApicsAreDetected()) { ret = x86IoApic::detectIoApics(); if (ret != ERROR_SUCCESS) { return ret; }; }; /* The i8254 is the only device which should be operational right * now. Disable it to force it to forget its __kpin assignment, then * mask all of the i8259 PIC pins. **/ if (i8254Pit.isEnabled()) { i8254WasEnabled = 1; }; if (i8254Pit.isSoftEnabled()) { i8254WasSoftEnabled = 1; }; printf(NOTICE CPUMOD"setSmpMode: i8254: wasEnabled=%d, " "wasSoftEnabled=%d.\n", i8254WasEnabled, i8254WasSoftEnabled); i8254Pit.setSmpModeSwitchFlag( cpuTrib.getCurrentCpuStream() ->taskStream.getCurrentThread()->getFullId()); printf(NOTICE CPUMOD"setSmpMode: Waiting for devices to disable.\n"); if (i8254WasEnabled) { i8254Pit.disable(); taskTrib.block(); }; i8254Pit.unsetSmpModeSwitchFlag(); /** EXPLANATION * Next, we parse the MP tables to see if the chipset has the IMCR * implemented. If so, we turn on Symm. I/O mode. * * If there are no MP tables, the chipset is assumed to be in virtual * wire mode. **/ mpFp = x86Mp::findMpFp(); if (mpFp != NULL && FLAG_TEST(mpFp->features[1], x86_MPFP_FEAT1_FLAG_PICMODE)) { ibmPcState.smpInfo.chipsetOriginalState = SMPSTATE_UNIPROCESSOR; // Enable Symm. I/O mode using IMCR. cpuControl::safeDisableInterrupts(&cpuFlags); io::write8(0x22, 0x70); io::write8(0x23, 0x1); cpuControl::safeEnableInterrupts(cpuFlags); printf(NOTICE CPUMOD"setSmpMode: chipset was in PIC " "mode.\n"); } else { ibmPcState.smpInfo.chipsetOriginalState = SMPSTATE_SMP; printf(NOTICE CPUMOD"setSmpMode: chipset was in Virtual " "wire mode.\n"); }; ibmPcState.smpInfo.chipsetState = SMPSTATE_SMP; assert_fatal( zkcmCore.irqControl.bpm.loadBusPinMappings(CC"isa") == ERROR_SUCCESS); printf(NOTICE CPUMOD"setSmpMode: Re-enabling devices.\n"); if (i8254WasEnabled) { ret = i8254Pit.enable(); if (ret != ERROR_SUCCESS) { printf(ERROR CPUMOD"setSmpMode: i8254 enable() " "failed.\n"); return ret; }; if (!i8254WasSoftEnabled) { i8254Pit.softDisable(); }; }; zkcmCore.irqControl.chipsetEventNotification( IRQCTL_EVENT_SMP_MODE_SWITCH, 0); return ERROR_SUCCESS; }
gboolean clientFocusNew(Client * c) { ScreenInfo *screen_info; DisplayInfo *display_info; gboolean give_focus; gboolean prevent_focus_stealing; gboolean prevented; g_return_val_if_fail (c != NULL, FALSE); screen_info = c->screen_info; display_info = screen_info->display_info; give_focus = (c-> type & WINDOW_REGULAR_FOCUSABLE) && (screen_info->params->focus_new); prevent_focus_stealing = screen_info->params->prevent_focus_stealing; prevented = FALSE; /* Try to avoid focus stealing */ if (!clientAcceptFocus (c) || (c->type & WINDOW_TYPE_DONT_FOCUS)) { give_focus = FALSE; } else if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_USER_TIME) && (c->user_time == (guint32) 0)) { /* * _NET_WM_USER_TIME definition from http://standards.freedesktop.org/wm-spec * [...] "The special value of zero on a newly mapped window can be used to * request that the window not be initially focused when it is mapped." */ TRACE ("given startup time is nil, not focusing \"%s\"", c->name); give_focus = FALSE; prevented = FALSE; } else if ((client_focus) && (prevent_focus_stealing)) { if (client_focus->win_layer > c->win_layer) { TRACE ("not focusing \"%s\" because the current focused window is on a upper layer", c->name); give_focus = FALSE; prevented = TRUE; } else if (client_focus->win_layer < c->win_layer) { /* We don't use focus stealing prevention against upper layers */ TRACE ("ignoring startup prevention because the current focused window is on a lower layer"); give_focus = TRUE; prevented = FALSE; } else if (FLAG_TEST (client_focus->xfwm_flags, XFWM_FLAG_MOVING_RESIZING)) { give_focus = FALSE; prevented = TRUE; } else if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_STARTUP_TIME | CLIENT_FLAG_HAS_USER_TIME)) { TRACE ("current time is %u, time for \"%s\" is %u", (unsigned int) client_focus->user_time, c->name, (unsigned int) c->user_time); if (TIMESTAMP_IS_BEFORE (c->user_time, client_focus->user_time)) { give_focus = FALSE; prevented = TRUE; } } } if (FLAG_TEST(c->flags, CLIENT_FLAG_STATE_MODAL)) { give_focus = TRUE; } if (give_focus) { if (client_focus) { clientAdjustFullscreenLayer (client_focus, FALSE); } clientRaise (c, None); clientShow (c, TRUE); clientSetFocus (screen_info, c, myDisplayGetCurrentTime (display_info), FOCUS_IGNORE_MODAL); } else { Client *c2 = clientGetFocus(); clientSortRing(c); if ((c2 != NULL) && (c2->win_layer == c->win_layer) && prevented) { /* * Place windows under the currently focused only if focus * stealing prevention had prevented the focus transition, * otherwise, leave the unfocused window on top. */ clientLower (c, c2->frame); } else { clientRaise (c, None); } clientSortRing(c2); if (prevented) { TRACE ("setting WM_STATE_DEMANDS_ATTENTION flag on \"%s\" (0x%lx)", c->name, c->window); FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION); } clientShow (c, TRUE); clientSetNetState (c); } return (give_focus); }
void workspaceSwitch (ScreenInfo *screen_info, gint new_ws, Client * c2, gboolean update_focus, guint32 timestamp) { DisplayInfo *display_info; Client *c, *new_focus; Client *previous; GList *list; Window dr, window; gint rx, ry, wx, wy; unsigned int mask; g_return_if_fail (screen_info != NULL); TRACE ("entering workspaceSwitch"); display_info = screen_info->display_info; if ((new_ws == (gint) screen_info->current_ws) && (screen_info->params->toggle_workspaces)) { new_ws = (gint) screen_info->previous_ws; } if (new_ws == (gint) screen_info->current_ws) { return; } if (screen_info->params->wrap_cycle) { if (new_ws > (gint) screen_info->workspace_count - 1) { new_ws = 0; } if (new_ws < 0) { new_ws = (gint) screen_info->workspace_count - 1; } } else if ((new_ws > (gint) screen_info->workspace_count - 1) || (new_ws < 0)) { return; } screen_info->previous_ws = screen_info->current_ws; screen_info->current_ws = new_ws; new_focus = NULL; previous = NULL; c = clientGetFocus (); if (c2) { clientSetWorkspace (c2, new_ws, FALSE); } if (c) { if (c->type & WINDOW_REGULAR_FOCUSABLE) { previous = c; } if (c2 == c) { new_focus = c2; } } /* First pass: Show, from top to bottom */ for (list = g_list_last(screen_info->windows_stack); list; list = g_list_previous (list)) { c = (Client *) list->data; if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)) { clientSetWorkspace (c, new_ws, TRUE); } else if (new_ws == (gint) c->win_workspace) { if (!FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED) && !FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE)) { if (!clientIsTransientOrModal (c) || !clientTransientOrModalHasAncestor (c, new_ws)) { clientShow (c, FALSE); } } } } /* Second pass: Hide from bottom to top */ for (list = screen_info->windows_stack; list; list = g_list_next (list)) { c = (Client *) list->data; if (new_ws != (gint) c->win_workspace) { if (c == previous) { FLAG_SET (previous->xfwm_flags, XFWM_FLAG_FOCUS); clientSetFocus (screen_info, NULL, timestamp, FOCUS_IGNORE_MODAL); } if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE) && !FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)) { if (!clientIsTransientOrModal (c) || !clientTransientOrModalHasAncestor (c, new_ws)) { clientWithdraw (c, new_ws, FALSE); } } } } /* Third pass: Check for focus, from top to bottom */ for (list = g_list_last(screen_info->windows_stack); list; list = g_list_previous (list)) { c = (Client *) list->data; if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)) { if ((!new_focus) && (c == previous) && clientSelectMask (c, NULL, 0, WINDOW_REGULAR_FOCUSABLE)) { new_focus = c; } FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_FOCUS); } else if (new_ws == (gint) c->win_workspace) { if ((!new_focus) && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_FOCUS)) { new_focus = c; } FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_FOCUS); } } setNetCurrentDesktop (display_info, screen_info->xroot, new_ws); if (!(screen_info->params->click_to_focus)) { if (!(c2) && (XQueryPointer (myScreenGetXDisplay (screen_info), screen_info->xroot, &dr, &window, &rx, &ry, &wx, &wy, &mask))) { c = clientAtPosition (screen_info, rx, ry, NULL); if (c) { new_focus = c; } } } if (update_focus) { if (new_focus) { if ((screen_info->params->click_to_focus) && (screen_info->params->raise_on_click)) { if (!(screen_info->params->raise_on_focus) && !clientIsTopMost (new_focus)) { clientRaise (new_focus, None); } } clientSetFocus (screen_info, new_focus, timestamp, FOCUS_SORT); } else { clientFocusTop (screen_info, WIN_LAYER_FULLSCREEN, timestamp); } } }
void clientMaxSpace (ScreenInfo *screen_info, int *x, int *y, int *w, int *h) { Client *c2; guint i; gint delta, screen_width, screen_height; g_return_if_fail (x != NULL); g_return_if_fail (y != NULL); g_return_if_fail (w != NULL); g_return_if_fail (h != NULL); screen_width = 0; screen_height = 0; delta = 0; for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++) { if (FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE)) { screen_width = c2->screen_info->width; screen_height = c2->screen_info->height; /* Left */ if (overlap (*x, *y, *x + *w, *y + *h, 0, c2->struts[STRUTS_LEFT_START_Y], c2->struts[STRUTS_LEFT], c2->struts[STRUTS_LEFT_END_Y])) { delta = c2->struts[STRUTS_LEFT] - *x; *x = *x + delta; *w = *w - delta; } /* Right */ if (overlap (*x, *y, *x + *w, *y + *h, screen_width - c2->struts[STRUTS_RIGHT], c2->struts[STRUTS_RIGHT_START_Y], screen_width, c2->struts[STRUTS_RIGHT_END_Y])) { delta = (*x + *w) - screen_width + c2->struts[STRUTS_RIGHT]; *w = *w - delta; } /* Top */ if (overlap (*x, *y, *x + *w, *y + *h, c2->struts[STRUTS_TOP_START_X], 0, c2->struts[STRUTS_TOP_END_X], c2->struts[STRUTS_TOP])) { delta = c2->struts[STRUTS_TOP] - *y; *y = *y + delta; *h = *h - delta; } /* Bottom */ if (overlap (*x, *y, *x + *w, *y + *h, c2->struts[STRUTS_BOTTOM_START_X], screen_height - c2->struts[STRUTS_BOTTOM], c2->struts[STRUTS_BOTTOM_END_X], screen_height)) { delta = (*y + *h) - screen_height + c2->struts[STRUTS_BOTTOM]; *h = *h - delta; } } } }
void clientFill (Client * c, int fill_type) { ScreenInfo *screen_info; Client *east_neighbour; Client *west_neighbour; Client *north_neighbour; Client *south_neighbour; Client *c2; GdkRectangle rect; XWindowChanges wc; unsigned short mask; guint i; gint cx, cy, full_x, full_y, full_w, full_h; gint tmp_x, tmp_y, tmp_w, tmp_h; g_return_if_fail (c != NULL); TRACE ("entering clientFill"); if (!CLIENT_CAN_FILL_WINDOW (c)) { return; } screen_info = c->screen_info; mask = 0; east_neighbour = NULL; west_neighbour = NULL; north_neighbour = NULL; south_neighbour = NULL; for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++) { /* Filter out all windows which are not visible, or not on the same layer * as well as the client window itself */ if ((c != c2) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE) && (c2->win_layer == c->win_layer)) { /* Fill horizontally */ if (fill_type & CLIENT_FILL_HORIZ) { /* * check if the neigbour client (c2) is located * east or west of our client. */ if (segment_overlap (frameY(c), frameY(c) + frameHeight(c), frameY(c2), frameY(c2) + frameHeight(c2))) { if ((frameX(c2) + frameWidth(c2)) <= frameX(c)) { if (west_neighbour) { /* Check if c2 is closer to the client * then the west neighbour already found */ if ((frameX(west_neighbour) + frameWidth(west_neighbour)) < (frameX(c2) + frameWidth(c2))) { west_neighbour = c2; } } else { west_neighbour = c2; } } if ((frameX(c) + frameWidth(c)) <= frameX(c2)) { /* Check if c2 is closer to the client * then the west neighbour already found */ if (east_neighbour) { if (frameX(c2) < frameX(east_neighbour)) { east_neighbour = c2; } } else { east_neighbour = c2; } } } } /* Fill vertically */ if (fill_type & CLIENT_FILL_VERT) { /* check if the neigbour client (c2) is located * north or south of our client. */ if (segment_overlap (frameX(c), frameX(c) + frameWidth(c), frameX(c2), frameX(c2) + frameWidth(c2))) { if ((frameY(c2) + frameHeight(c2)) <= frameY(c)) { if (north_neighbour) { /* Check if c2 is closer to the client * then the north neighbour already found */ if ((frameY(north_neighbour) + frameHeight(north_neighbour)) < (frameY(c2) + frameHeight(c2))) { north_neighbour = c2; } } else { north_neighbour = c2; } } if ((frameY(c) + frameHeight(c)) <= frameY(c2)) { if (south_neighbour) { /* Check if c2 is closer to the client * then the south neighbour already found */ if (frameY(c2) < frameY(south_neighbour)) { south_neighbour = c2; } } else { south_neighbour = c2; } } } } } } /* Compute the largest size available, based on struts, margins and Xinerama layout */ tmp_x = frameX (c); tmp_y = frameY (c); tmp_h = frameHeight (c); tmp_w = frameWidth (c); cx = tmp_x + (tmp_w / 2); cy = tmp_y + (tmp_h / 2); myScreenFindMonitorAtPoint (screen_info, cx, cy, &rect); full_x = MAX (screen_info->params->xfwm_margins[STRUTS_LEFT], rect.x); full_y = MAX (screen_info->params->xfwm_margins[STRUTS_TOP], rect.y); full_w = MIN (screen_info->width - screen_info->params->xfwm_margins[STRUTS_RIGHT], rect.x + rect.width) - full_x; full_h = MIN (screen_info->height - screen_info->params->xfwm_margins[STRUTS_BOTTOM], rect.y + rect.height) - full_y; if ((fill_type & CLIENT_FILL) == CLIENT_FILL) { mask = CWX | CWY | CWHeight | CWWidth; /* Adjust size to the largest size available, not covering struts */ clientMaxSpace (screen_info, &full_x, &full_y, &full_w, &full_h); } else if (fill_type & CLIENT_FILL_VERT) { mask = CWY | CWHeight; /* Adjust size to the tallest size available, for the current horizontal position/width */ clientMaxSpace (screen_info, &tmp_x, &full_y, &tmp_w, &full_h); } else if (fill_type & CLIENT_FILL_HORIZ) { mask = CWX | CWWidth; /* Adjust size to the widest size available, for the current vertical position/height */ clientMaxSpace (screen_info, &full_x, &tmp_y, &full_w, &tmp_h); } /* If there are neighbours, resize to their borders. * If not, resize to the largest size available that you just have computed. */ wc.x = full_x + frameLeft(c); if (west_neighbour) { wc.x += MAX (frameX(west_neighbour) + frameWidth(west_neighbour) - full_x, 0); } wc.width = full_w - frameRight(c) - (wc.x - full_x); if (east_neighbour) { wc.width -= MAX (full_w - (frameX(east_neighbour) - full_x), 0); } wc.y = full_y + frameTop(c); if (north_neighbour) { wc.y += MAX (frameY(north_neighbour) + frameHeight(north_neighbour) - full_y, 0); } wc.height = full_h - frameBottom(c) - (wc.y - full_y); if (south_neighbour) { wc.height -= MAX (full_h - (frameY(south_neighbour) - full_y), 0); } TRACE ("Fill size request: (%d,%d) %dx%d", wc.x, wc.y, wc.width, wc.height); if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED)) { clientConfigure(c, &wc, mask, NO_CFG_FLAG); } }
void walkerPageRanger::remapNoInc( VaddrSpace *vaddrSpace, void *vaddr, paddr_t paddr, uarch_t nPages, ubit8 op, uarch_t __kflags ) { uarch_t l0Start, l0Current, l0End; uarch_t l1Start, l1Current, l1Limit, l1End; paddr_t l0Entry, l1Entry; #ifdef CONFIG_ARCH_x86_32_PAE uarch_t l2Start, l2Current, l2Limit, l2End; paddr_t l2Entry; #endif uarch_t archFlags, localFlush; if (nPages == 0) { return; }; localFlush = FLAG_TEST(__kflags, PAGEATTRIB_LOCAL_FLUSH_ONLY); vaddr = reinterpret_cast<void *>( (uarch_t)vaddr & PAGING_BASE_MASK_HIGH ); archFlags = walkerPageRanger::encodeFlags(__kflags); getLevelRanges( vaddr, nPages, &l0Start, &l0End, &l1Start, &l1End #ifdef CONFIG_ARCH_x86_32_PAE ,&l2Start, &l2End #endif ); // This is SRS BSNS. Lock off both address spaces. vaddrSpace->level0Accessor.lock.acquire(); cpuTrib.getCurrentCpuStream()->taskStream.getCurrentThread()->parent ->getVaddrSpaceStream()->vaddrSpace .level0Accessor.lock.acquire(); l0Current = l0Start; for (; l0Current <= l0End; l0Current++) { l0Entry = vaddrSpace->level0Accessor.rsrc->entries[l0Current]; *level1Modifier = l0Entry; tlbControl::flushSingleEntry((void *)level1Accessor); l1Current = ((l0Current == l0Start) ? l1Start : 0); l1Limit = ((l0Current == l0End) ? l1End : (PAGING_L1_NENTRIES - 1)); for (; l1Current <= l1Limit; l1Current++) { #ifdef CONFIG_ARCH_x86_32_PAE l1Entry = level1Accessor->entries[l1Current]; *level2Modifier = l1Entry; tlbControl::flushSingleEntry((void *)level2Accessor); l2Current = (((l0Current == l0Start) && (l1Current == l1Start)) ? l2Start : 0); l2Limit = (((l0Current == l0End) && (l1Current == l1End)) ? l2End : (PAGING_L2_NENTRIES - 1)) for (; l2Current < l2Limit; l2Current++) { l2Entry = level2Accessor->entries[l2Current] & 0xFFF; level2Accessor->entries[l2Current] = 0; level2Accessor->entries[l2Current] |= l2Entry; switch (op) { case WPRANGER_OP_SET: { FLAG_SET( level2Accessor ->entries[l2Current], archFlags); break; }; case WPRANGER_OP_CLEAR: { FLAG_UNSET( level2Accessor ->entries[l2Current], archFlags); break; }; case WPRANGER_OP_SET_PRESENT: { FLAG_SET( level2Accessor ->entries[l2Current], PAGING_L2_PRESENT); break; }; case WPRANGER_OP_CLEAR_PRESENT: { FLAG_UNSET( level2Accessor ->entries[l2Current], PAGING_L2_PRESENT); break; }; case WPRANGER_OP_SET_WRITE: { FLAG_SET( level2Accessor ->entries[l2Current], PAGING_L2_WRITE); break; }; case WPRANGER_OP_CLEAR_WRITE: { FLAG_UNSET( level2Accessor ->entries[l2Current], PAGING_L2_WRITE); break; }; default: break; }; level2Accessor->entries[l2Current] |= paddr; }; #else l1Entry = level1Accessor->entries[l1Current] & 0xFFF; level1Accessor->entries[l1Current] = 0; level1Accessor->entries[l1Current] |= l1Entry; switch (op) { case WPRANGER_OP_SET: { FLAG_SET( level1Accessor->entries[l1Current], archFlags); break; }; case WPRANGER_OP_CLEAR: { FLAG_UNSET( level1Accessor->entries[l1Current], archFlags); break; }; case WPRANGER_OP_SET_PRESENT: { FLAG_SET( level1Accessor ->entries[l1Current], PAGING_L1_PRESENT); break; }; case WPRANGER_OP_CLEAR_PRESENT: { FLAG_UNSET( level1Accessor ->entries[l1Current], PAGING_L1_PRESENT); break; }; case WPRANGER_OP_SET_WRITE: { FLAG_SET( level1Accessor ->entries[l1Current], PAGING_L1_WRITE); break; }; case WPRANGER_OP_CLEAR_WRITE: { FLAG_UNSET( level1Accessor ->entries[l1Current], PAGING_L1_WRITE); break; }; default: break; }; level1Accessor->entries[l1Current] |= paddr; #endif }; }; #if __SCALING__ > SCALING_SMP if (localFlush) { tlbControl::flushEntryRange(vaddr, nPages); } else { tlbControl::smpFlushEntryRange(vaddr, nPages); }; #else tlbControl::flushEntryRange(vaddr, nPages); #endif vaddrSpace->level0Accessor.lock.release(); cpuTrib.getCurrentCpuStream()->taskStream.getCurrentThread()->parent ->getVaddrSpaceStream()->vaddrSpace .level0Accessor.lock.release(); /* FIXME: * Insert code here to propagate possible changes to the kernel * address space into the other process address spaces. **/ // We make the assumption that this did not fail. }
static void smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) { Client *c2; ScreenInfo *screen_info; gfloat best_overlaps; guint i; gint test_x, test_y, xmax, ymax, best_x, best_y; gint frame_height, frame_width, frame_left, frame_top; gboolean first; gint c2_x, c2_y; g_return_if_fail (c != NULL); TRACE ("entering smartPlacement"); screen_info = c->screen_info; frame_height = frameHeight (c); frame_width = frameWidth (c); frame_left = frameLeft(c); frame_top = frameTop (c); test_x = 0; test_y = 0; best_overlaps = 0.0; first = TRUE; xmax = full_x + full_w - c->width - frameRight (c); ymax = full_y + full_h - c->height - frameBottom (c); best_x = full_x + frameLeft (c); best_y = full_y + frameTop (c); test_y = full_y + frameTop (c); do { test_x = full_x + frameLeft (c); do { gfloat count_overlaps = 0.0; TRACE ("analyzing %i clients", screen_info->client_count); for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++) { if ((c2 != c) && (c2->type != WINDOW_DESKTOP) && (c->win_workspace == c2->win_workspace) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE)) { c2_x = frameX (c2); c2_y = frameY (c2); count_overlaps += overlap (test_x - frame_left, test_y - frame_top, test_x - frame_left + frame_width, test_y - frame_top + frame_height, c2_x, c2_y, c2_x + frameWidth (c2), c2_y + frameHeight (c2)); } } if (count_overlaps < 0.1) { TRACE ("overlaps is 0 so it's the best we can get"); c->x = test_x; c->y = test_y; return; } else if ((count_overlaps < best_overlaps) || (first)) { best_x = test_x; best_y = test_y; best_overlaps = count_overlaps; } if (first) { first = FALSE; } test_x += 8; } while (test_x <= xmax); test_y += 8; } while (test_y <= ymax); c->x = best_x; c->y = best_y; }