Get the window handle in PyGI on MacOS - macos

I use PyGObject/PyGI and GStreamer to show a video in my GUI. The video is shown in a Gtk.DrawingArea and therefore I need to get it's window-handle in the realize-signal-handler. On Linux I can simply use drawing_area.get_property('window').get_xid() and on Windows I have to access the C-API (like described here):
drawingarea_window = drawingarea.get_property('window')
ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p
ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object]
drawingarea_gpointer = ctypes.pythonapi.PyCapsule_GetPointer(drawingarea_window.__gpointer__, None)
gdkdll = ctypes.CDLL ('libgdk-3-0.dll')
self._drawingarea_handle = gdkdll.gdk_win32_window_get_handle(drawingarea_gpointer)
Now I want the same on MacOS. Since it is not using X11, but Quartz, I tried to use the C-API again. But this time to call gdk_quartz_window_get_nswindow instead of gdk_win32_window_get_handle (see gdkwindow-quartz.c):
// ... same lines as in Windows-example
gdkdll = ctypes.CDLL ('libgdk-3.0.dylib')
self._drawingarea_handle = gdkdll.gdk_quartz_window_get_nswindow(drawingarea_gpointer)
But this leads just to a Segmentation fault: 11.Any ideas on how to get the handle on MacOS?

Related

MacOs OpenGl forward compatibilty?

I am trying to set up some very simple graphic windows which I also have to use on MacOS version Big Sur unfortunately. I am using the F# programming language and the OpenTK package.
This is the code I have at the moment.
open OpenTK.Windowing.Desktop
open OpenTK.Mathematics
open OpenTK.Windowing.Common
open OpenTK.Graphics
[<EntryPoint>]
let main argv =
let prof = ContextProfile.Compatability
let windowSettings = NativeWindowSettings()
windowSettings.Size <- Vector2i(800, 600)
windowSettings.Title <- "OpenTK Window"
windowSettings.Profile <- prof
windowSettings.APIVersion <- Version "3.3"
use window = new GameWindow(GameWindowSettings.Default, windowSettings)
//window.MakeCurrent()
//window.Run ()
0
Whenever I run this I get:
Unhandled exception. OpenTK.Windowing.GraphicsLibraryFramework.GLFWException: NSGL: The targeted version of macOS only supports forward-compatible core profile contexts for OpenGL 3.2 and above
at OpenTK.Windowing.Desktop.GLFWProvider.<>c.<.cctor>b__5_0(ErrorCode errorCode, String description)
I have tried every single configuration possible but I am stumped, is there anyone that can give me a pointer on how to set the compatibility for this?
Change this
let prof = ContextProfile.Compatability
to
let prof = ContextProfile.Core

Save a figure to file with specific resolution

In an old version of my code, I used to do a hardcopy() with a given resolution, ie:
frame = hardcopy(figHandle, ['-d' renderer], ['-r' num2str(round(pixelsperinch))]);
For reference, hardcopy saves a figure window to file.
Then I would typically perform:
ZZ = rgb2gray(frame) < 255/2;
se = strel('disk',diskSize);
ZZ2 = imdilate(ZZ,se); %perform dilation.
Surface = bwarea(ZZ2); %get estimated surface (in pixels)
This worked until I switched to Matlab 2017, in which the hardcopy() function is deprecated and we are left with the print() function instead.
I am unable to extract the data from figure handler at a specific resolution using print. I've tried many things, including:
frame = print(figHandle, '-opengl', strcat('-r',num2str(round(pixelsperinch))));
But it doesn't work. How can I overcome this?
EDIT
I don't want to 'save' nor create a figure file, my aim is to extract the data from the figure in order to mesure a surface after a dilation process. I just want to keep this information and since 'im processing a LOT of different trajectories (total is approx. 1e7 trajectories), i don't want to save each file to disk (this is costly, time execution speaking). I'm running this code on a remote server (without a graphic card).
The issue I'm struggling with is: "One or more output arguments not assigned during call to "varargout"."
getframe() does not allow for setting a specific resolution (it uses current resolution instead as far as I know)
EDIT2
Ok, figured out how to do, you need to pass the '-RGBImage' argument like this:
frame = print(figHandle, ['-' renderer], ['-r' num2str(round(pixelsperinch))], '-RGBImage');
it also accept custom resolution and renderer as specified in the documentation.
I think you must specify formattype too (-dtiff in my case). I've tried this in Matlab 2016b with no problem:
print(figHandle,'-dtiff', '-opengl', '-r600', 'nameofmyfig');
EDIT:
If you need the CData just find the handle of the corresponding axes and get its CData
f = findobj('Tag','mytag')
Then depending on your matlab version use:
mycdata = get(f,'CData');
or directly
mycdta = f.CData;
EDIT 2:
You can set the tag of your image programatically and then do what I said previously:
a = imshow('peppers.png');
set(a,'Tag','mytag');

Python text color doesn't work on Windows

I'm trying to get this snippet to work, but it seems it won't work in Windows. Under Linux it works just fine!
Here is the sample snippet of code demonstrating the usage:
tops = []
for ind, top in enumerate(lr.top):
color = colors.setdefault(top, COLORS[len(colors) % len(COLORS)])
if top in disconnected_tops:
top = '\033[1;4m' + top
if len(lr.loss_weight) > 0:
top = '{} * {}'.format(lr.loss_weight[ind], top)
tops.append('\033[{}m{}\033[0m'.format(color, top))
top_str = ', '.join(tops)
When the whole script is run, the escape character seems not to be working and weird characters show up on the screen. How do I get this to work on Windows?
I found the problem!
I had to use init() in the script that was missing originally!.
Seems init() is not needed in Linux based OSes!since if it were!, this shouldn't had worked there in first place!
Ok.Here is the documentation itself!:
On Windows, calling init() will filter ANSI escape sequences out of
any text sent to stdout or stderr, and replace them with equivalent
Win32 calls.
On other platforms, calling init() has no effect (unless you request
other optional functionality; see “Init Keyword Args”, below). By
design, this permits applications to call init() unconditionally on
all platforms, after which ANSI output should just work.

AVSpeechUtterance Not Working

In IOS 8 AVSpeechUtterance is Not Working. Every time I use AVSpeechSynthesizer along with AVSpeechUtterance, I get "Speech initialization error: 2147483665". The same code works fine for IOS 7.1 I have a very large text to convert to speech, and using Google TTS won't allow me to use more than 100 characters at a time. How can I implement text-to-speech in IOS 8? Any help will be appreciated.
See this topic, and linked question also: AVSpeechSynthesizer iOS 8 Issues
For me, TTS on iOS work only on real device, not simulator. But iOS8 still have some problems with voices, some workaround mentioned in questions above.
Also, please mention this (user should set some settings): Using AVSpeechSynthesizer/AVSpeechUtterance for Text-To-Speech will not work if SpeakSelection is not enabled in device's Accessiblity settings
First import Speech
import Speech
Secondly define global variable for AVSpeechSynthesizer
let speakTalk = AVSpeechSynthesizer()
Create function Audio to take input as string
func Audio(Input : String)
{
let speakText = AVSpeechUtterance(string: "\(Input)")
speakText.rate = 0.5
speakText.pitchMultiplier = 1.7
speakTalk.speak(speakText)
}
call func Audio()
Audio(Input : "Hello")

How to get default volume on Mac OS X 64-bit?

What's the way to get default volume on Mac 64-bit?
I have a code like that:
GetVolParmsInfoBuffer buf_64 = { 0 };
status = FSGetVolumeParms(vol_ref, // use default volume
&buf_64, // write
req_count);
The problem is that I can't pass 0 in vol_ref. On Mac 32-bit I could write:
GetVolParmsInfoBuffer buf_32 = { 0 };
HParamBlockRec pb;
pb.ioParam.ioCompletion = NULL; // not doing async I/O
pb.ioParam.ioNamePtr = NULL; // we don't use path name
pb.ioParam.ioVRefNum = 0; // use default volume
pb.ioParam.ioBuffer = reinterpret_cast(&buf_32); // write data here
pb.ioParam.ioReqCount = req_count;
OSErr err = PBHGetVolParmsSync(&pb);
ASSERT_EQ(err, noErr);
Thanks in advance,
- Oleksii
In the File Manager docs, you'll notice a function group titled “Manipulating the Default Volume”. All of those functions are deprecated.
If you search Google for the functions therein, particularly HSetVol, you'll find this mailing list post by Eric Schlegel, which says HSetVol had the effect of setting the current working directory (expressed as a volume/directory pair) on Mac OS. He also says that it doesn't work on Mac OS X: It should work on File Manager functions, but does not set the working directory used for resolving relative paths in other APIs (e.g., open and fopen) like it did on Mac OS.
Moreover, those functions are not available in 64-bit Mac OS X. So the answer is: You don't, because there is no default volume.
The old meaning of it was analogous to the current working directory, so you can do the same thing by getting the CWD and resolving that path to an FSRef. However, for a Mac OS X application (particularly one that doesn't set the CWD by any means, as most don't), this is not terribly useful: The default CWD for an application is /, the root directory of the boot volume. On the other hand, if you run your executable directly or under Xcode's Debugger, its CWD will not be /, which means it could be some other volume—most probably, the one with your Home folder on it.
You should refer to the boot volume (or whatever volume you're interested in) specifically, not attempt to get or simulate getting the default (current working) directory.
For the boot volume, you might try kOnSystemDisk, which is one of the constants in the Folder Manager. If that doesn't work, use Folder Manager's FSFindFolder function to retrieve the System folder, then use File Manager's FSGetVolumeInfo function to get what volume it's on.
Well. I don't really know what "default volume" is. All I know is that Carbon manual (File Manager) says:
ioVRefNum
A volume reference number, 0 for the default volume, or a drive number.
Well, I seem to find the answer for my question.
FSVolumeInfoParam vol_info = { 0 };
vol_info.ioVRefNum = kFSInvalidVolumeRefNum; // will obtain it
vol_info.volumeIndex = 1; // XXX: is it the default volume as well?
vol_info.whichInfo = kFSVolInfoNone; // don't pass volume info
err = PBGetVolumeInfoSync(&vol_info);
The only thing I'm not sure of is if the 1st volume is the default one...
P.S. I guess the problem is that I don't quite understand what "default volume" really is ;-)

Resources