screen_info CreateDefaultScreenInfo(int DisplayIndex, int ScreenIndex) { CGRect DisplayRect = CGDisplayBounds(DisplayIndex); screen_info Screen; Screen.Identifier = GetDisplayIdentifier(DisplayIndex); Screen.ID = ScreenIndex; Screen.ActiveSpace = -1; Screen.TrackSpaceChange = true; Screen.X = DisplayRect.origin.x; Screen.Y = DisplayRect.origin.y; Screen.Width = DisplayRect.size.width; Screen.Height = DisplayRect.size.height; Screen.Settings.Offset = KWMScreen.DefaultOffset; Screen.Settings.Mode = SpaceModeDefault; DEBUG("Creating screen info for display ID: " << DisplayIndex << " Resolution: " << Screen.Width << "x" << Screen.Height << " Origin: (" << Screen.X << "," << Screen.Y << ")"); return Screen; }
PGENERIC_LIST CreateDisplayDriverList(HINF InfFile) { CHAR Buffer[128]; PGENERIC_LIST List; INFCONTEXT Context; PWCHAR KeyName; PWCHAR KeyValue; PWCHAR UserData; WCHAR DisplayIdentifier[128]; WCHAR DisplayKey[32]; /* Get the display identification */ if (!GetDisplayIdentifier(DisplayIdentifier, 128)) { DisplayIdentifier[0] = 0; } DPRINT("Display identifier: '%S'\n", DisplayIdentifier); /* Search for matching device identifier */ if (!SetupFindFirstLineW(InfFile, L"Map.Display", NULL, &Context)) { /* FIXME: error message */ return NULL; } do { if (!INF_GetDataField(&Context, 1, &KeyValue)) { /* FIXME: Handle error! */ DPRINT("INF_GetDataField() failed\n"); return NULL; } DPRINT("KeyValue: %S\n", KeyValue); if (wcsstr(DisplayIdentifier, KeyValue)) { if (!INF_GetDataField(&Context, 0, &KeyName)) { /* FIXME: Handle error! */ DPRINT("INF_GetDataField() failed\n"); return NULL; } DPRINT("Display key: %S\n", KeyName); wcscpy(DisplayKey, KeyName); } } while (SetupFindNextLine(&Context, &Context)); List = CreateGenericList(); if (List == NULL) return NULL; if (!SetupFindFirstLineW (InfFile, L"Display", NULL, &Context)) { DestroyGenericList(List, FALSE); return NULL; } do { if (!INF_GetDataField(&Context, 0, &KeyName)) { DPRINT1("INF_GetDataField() failed\n"); break; } if (!INF_GetDataField(&Context, 1, &KeyValue)) { DPRINT1("INF_GetDataField() failed\n"); break; } UserData = (WCHAR*) RtlAllocateHeap(ProcessHeap, 0, (wcslen(KeyName) + 1) * sizeof(WCHAR)); if (UserData == NULL) { DPRINT1("RtlAllocateHeap() failed\n"); DestroyGenericList(List, TRUE); return NULL; } wcscpy(UserData, KeyName); sprintf(Buffer, "%S", KeyValue); AppendGenericListEntry(List, Buffer, UserData, _wcsicmp(KeyName, DisplayKey) ? FALSE : TRUE); } while (SetupFindNextLine(&Context, &Context)); #if 0 AppendGenericListEntry(List, "Other display driver", NULL, TRUE); #endif return List; }
void DisplayReconfigurationCallBack(CGDirectDisplayID Display, CGDisplayChangeSummaryFlags Flags, void *UserInfo) { pthread_mutex_lock(&KWMThread.Lock); static int idx = 0; DEBUG("\n[" << idx << "] BEGIN DISPLAY CONFIGURATION CALLBACK"); if (Flags & kCGDisplayAddFlag) { CFStringRef displayIdentifier = GetDisplayIdentifier(Display); int savedDisplayID = 0; if(displayIdentifier) savedDisplayID = GetDisplayIDFromIdentifier(displayIdentifier); if (!savedDisplayID) { DEBUG("New display detected! DisplayID: " << Display << " Index: " << KWMScreen.ActiveCount); } else if (savedDisplayID != Display) { DEBUG("This display being added had saved ID: " << savedDisplayID); UpdateDisplayIDForDisplay(savedDisplayID, Display); } else { DEBUG("The display that is being added is already there!"); } // Display has been added RefreshActiveDisplays(true); } if (Flags & kCGDisplayRemoveFlag) { CFStringRef displayIdentifier = GetDisplayIdentifier(Display); int savedDisplayID = 0; if(displayIdentifier) savedDisplayID = GetDisplayIDFromIdentifier(displayIdentifier); if ((!savedDisplayID) || (savedDisplayID == Display)) { // Display has been removed if(CGDisplayIsAsleep(Display)) { DEBUG("Display " << Display << " is asleep!"); RefreshActiveDisplays(false); } else { DEBUG("Display has been removed! DisplayID: " << Display); std::map<int, space_info>::iterator It; for(It = KWMTiling.DisplayMap[Display].Space.begin(); It != KWMTiling.DisplayMap[Display].Space.end(); ++It) DestroyNodeTree(It->second.RootNode); if(KWMTiling.DisplayMap[Display].Identifier) CFRelease(KWMTiling.DisplayMap[Display].Identifier); KWMTiling.DisplayMap.erase(Display); RefreshActiveDisplays(true); } } else if (savedDisplayID != Display) { DEBUG("This display being removed had saved ID: " << savedDisplayID); RefreshActiveDisplays(true); } } if ((Flags & kCGDisplayDesktopShapeChangedFlag) || (Flags & kCGDisplayMovedFlag)) { if(!CGDisplayIsAsleep(Display)) { if (Flags & kCGDisplayDesktopShapeChangedFlag) { DEBUG("Display " << Display << " changed resolution"); } else { DEBUG("Display " << Display << " moved"); } screen_info *Screen = &KWMTiling.DisplayMap[Display]; UpdateExistingScreenInfo(Screen, Display, Screen->ID); std::map<int, space_info>::iterator It; for(It = Screen->Space.begin(); It != Screen->Space.end(); ++It) { if(It->second.Managed || It->second.Settings.Mode == SpaceModeFloating) { if(It->first == Screen->ActiveSpace) UpdateSpaceOfScreen(&It->second, Screen); else It->second.NeedsUpdate = true; } } } } if (Flags & kCGDisplaySetMainFlag) { DEBUG("Display " << Display << " became main"); } if (Flags & kCGDisplaySetModeFlag) { DEBUG("Display " << Display << " changed mode"); } if (Flags & kCGDisplayEnabledFlag) { DEBUG("Display " << Display << " enabled"); } if (Flags & kCGDisplayDisabledFlag) { DEBUG("Display " << Display << " disabled"); } DEBUG("[" << idx << "] END DISPLAY CONFIGURATION CALLBACK\n"); idx++; pthread_mutex_unlock(&KWMThread.Lock); }