/filesystems/grabfs/windowfs_windows.cc

http://macfuse.googlecode.com/ · C++ · 147 lines · 114 code · 25 blank · 8 comment · 26 complexity · bb29d3973b71291ad91513f03f9ce48f MD5 · raw file

  1. /*
  2. * MacFUSE-Based windowfs
  3. *
  4. * Copyright Amit Singh. All Rights Reserved.
  5. * http://osxbook.com
  6. *
  7. */
  8. #include <ApplicationServices/ApplicationServices.h>
  9. extern "C" {
  10. #include "windowfs_windows.h"
  11. static void
  12. WINDOWFS_WindowListApplierFunction(const void *inputDictionary, void *context)
  13. {
  14. CFDictionaryRef entry = (CFDictionaryRef)inputDictionary;
  15. WindowListData *data = (WindowListData *)context;
  16. CFNumberRef sharingState; /* SInt32 */
  17. CFNumberRef windowNumber; /* SInt64 */
  18. CFNumberRef ownerPID; /* SInt64 */
  19. Boolean status;
  20. SInt32 sint32;
  21. SInt64 sint64;
  22. status = CFDictionaryGetValueIfPresent(entry, kCGWindowSharingState,
  23. (const void **)&sharingState);
  24. if (status == true) {
  25. status = CFNumberGetValue(sharingState, kCFNumberSInt32Type,
  26. (void *)&sint32);
  27. CFRelease(sharingState);
  28. if ((status == true) && (sint32 == 0)) {
  29. return;
  30. }
  31. } else {
  32. /* proceed */
  33. }
  34. status = CFDictionaryGetValueIfPresent(entry, kCGWindowOwnerPID,
  35. (const void **)&ownerPID);
  36. if (status == true) {
  37. status = CFNumberGetValue(ownerPID, kCFNumberSInt64Type,
  38. (void *)&sint64);
  39. CFRelease(ownerPID);
  40. if (status == true) {
  41. if ((pid_t)sint64 != data->pid) {
  42. return;
  43. }
  44. } else {
  45. return;
  46. }
  47. } else {
  48. return;
  49. }
  50. status = CFDictionaryGetValueIfPresent(entry, kCGWindowNumber,
  51. (const void **)&windowNumber);
  52. if (status == true) {
  53. status = CFNumberGetValue(windowNumber, kCFNumberSInt64Type,
  54. (void *)&sint64);
  55. CFRelease(windowNumber);
  56. if (status == true) {
  57. data->windowIDs[data->windowCount] = (CGSWindowID)sint64;
  58. data->windowCount++;
  59. } else {
  60. return;
  61. }
  62. } else {
  63. return;
  64. }
  65. }
  66. int
  67. WINDOWFS_GetWindowList(WindowListData *data)
  68. {
  69. CFArrayRef windowList = CGWindowListCopyWindowInfo(
  70. kCGWindowListOptionOnScreenOnly,
  71. kCGNullWindowID);
  72. if (!windowList) {
  73. return -1;
  74. }
  75. CFArrayApplyFunction(windowList,
  76. CFRangeMake(0, CFArrayGetCount(windowList)),
  77. &WINDOWFS_WindowListApplierFunction, (void *)data);
  78. return data->windowCount;
  79. }
  80. off_t
  81. WINDOWFS_GetTIFFSizeForWindowAtIndex(CGWindowID index)
  82. {
  83. CGRect rect;
  84. CGError err = CGSGetScreenRectForWindow(_CGSDefaultConnection(), index,
  85. &rect);
  86. if (err) {
  87. return (off_t)0;
  88. }
  89. off_t size = ((off_t)rect.size.width * (off_t)rect.size.height * (off_t)4)
  90. + (off_t)8192;
  91. return size;
  92. }
  93. int
  94. WINDOWFS_GetTIFFForWindowAtIndex(CGWindowID index, CFMutableDataRef *data)
  95. {
  96. *data = (CFMutableDataRef)0;
  97. CGImageRef image = CGWindowListCreateImage(
  98. CGRectNull, kCGWindowListOptionIncludingWindow,
  99. index, kCGWindowImageBoundsIgnoreFraming);
  100. if (!image) {
  101. return -1;
  102. }
  103. *data = CFDataCreateMutable(kCFAllocatorDefault, 0);
  104. if (!*data) {
  105. CFRelease(image);
  106. return -1;
  107. }
  108. CGImageDestinationRef dest =
  109. CGImageDestinationCreateWithData((CFMutableDataRef)*data, kUTTypeTIFF,
  110. 1, nil);
  111. if (!dest) {
  112. CFRelease(*data);
  113. CFRelease(image);
  114. return -1;
  115. }
  116. CGImageDestinationAddImage(dest, image, nil);
  117. CGImageDestinationFinalize(dest);
  118. CFRelease(dest);
  119. CGImageRelease(image);
  120. return 0;
  121. }
  122. } /* extern "C" */