Skip to content

It is unclear how to get a CGImage from a *mut CGImage #373

Open
@ethanpailes

Description

@ethanpailes

As a disclaimer, I have a suspicion that what I want to do is possible with the API that already exists, but I've just been unable to figure out how to do it. If that turns out to be the case, I'll open up a documentation PR as a follow up.

I've been trying to create a CGImage from the *mut CGImage that the CGWindowListCreateImage routine returns, but it is not clear to me how this can be accomplished with the public API that core_graphics exposes. In particular, by grepping the sources of core_foundation itself, it seems like the CGImage::from_ptr method is what I want, but that method is attached to the ForeignType trait which is not publicly exposed.

To make this a little more concrete, here is some code that I would like to be able to write:

use core_graphics::image::CGImage;
use core_graphics::display::{
    CGWindowListCreateImage, kCGWindowListOptionIncludingWindow,
    kCGWindowImageBoundsIgnoreFraming, kCGWindowImageBestResolution, CGRectNull
};
use core_graphics::foreign_types::ForeignType;

fn main() {
    let img = unsafe {
        CGWindowListCreateImage(
            CGRectNull,
            kCGWindowListOptionIncludingWindow,
            0, // fake window id, in real life would be fetched with other CG calls
            kCGWindowImageBoundsIgnoreFraming | kCGWindowImageBestResolution,
        )
    };
    if img.is_null() {
        panic!("null ptr");
    }
    let _ = unsafe { CGImage::from_ptr(img) };
}

Unfortunately, this doesn't work:

$ cargo check
    Checking rs v0.1.0 (/Users/ethanpailes/repos/mucking/rs)
error[E0603]: crate `foreign_types` is private
  --> src/main.rs:6:20
   |
6  | use core_graphics::foreign_types::ForeignType;
   |                    ^^^^^^^^^^^^^ this crate is private
   |
note: the crate `foreign_types` is defined here
  --> /Users/ethanpailes/.cargo/registry/src/github.jpy.wang-1ecc6299db9ec823/core-graphics-0.19.0/src/lib.rs:20:1
   |
20 | extern crate foreign_types;
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0603`.
error: could not compile `rs`.

To learn more, run the command again with --verbose.

My temporary work around for this issue is to apply the following patch to my fork of core-foundation-rs:

diff --git a/core-graphics/src/lib.rs b/core-graphics/src/lib.rs
index 6468af8..41cbccd 100644
--- a/core-graphics/src/lib.rs
+++ b/core-graphics/src/lib.rs
@@ -17,7 +17,7 @@ extern crate core_foundation;
 extern crate bitflags;
 
 #[macro_use]
-extern crate foreign_types;
+pub extern crate foreign_types;
 
 pub mod base;
 pub mod color;

This works fine for my use case, but it feels pretty hacky. I feel like I must be missing something if I have to punch such a big hole in the privacy boundary of core_graphics in order to get my code to compile.

Sorry in advance if there is a really obvious way to do this that I'm missing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions