Ocaml not able to find Labltk - window

I am working on Debian Stable and have installed ocaml and opam from Debian repositories. I am trying following code from here:
#directory "+labltk"
#load "labltk.cma"
let () =
let top = Tk.openTk() in
Wm.title_set top "Tk-OCaml Example";
let label = Label.create ~text:"There have been no clicks yet" top in
let b =
Button.create
~text:"click me"
~command:(fun () -> Tk.closeTk (); exit 0)
top
in
Tk.pack [Tk.coe label; Tk.coe b];
Tk.mainLoop ();
;;
However, I am getting following error:
$ ocaml simplewin.ml
Cannot find file labltk.cma.
File "simplewin.ml", line 5, characters 12-21:
Error: Unbound module Tk
I have labltk module installed:
$ opam list labltk
# Available packages for system:
labltk 8.06.0 OCaml interface to Tcl/Tk, including OCaml library explorer OCamlBrowser
Where is the problem and how can this be solved? Thanks for your help.

Labltk is no longer distributed along the compiler since OCaml 4.02. Consequently,
#directory "+labltk";;
#load "labltk.cma";;
is not the right command: you should use
#require "labltk";;
EDIT: The following code works for me:
#require "labltk";;
let () =
let top = Tk.openTk() in
Wm.title_set top "Tk-OCaml Example";
let label =
Label.create ~text:"There have been no clicks yet" top in
let b =
Button.create
~text:"click me"
~command:(fun () -> Tk.closeTk (); exit 0)
top
in
Tk.pack [Tk.coe label; Tk.coe b];
Tk.mainLoop ();
;;

Related

Haskell - Converting multiple images into a video file - ffmpeg-lights' frameWriter-function fails

Situation
Currently I am working on an application for image-processing that uses ffmpeg-light to fetch all the frames of a given video-file so that the program afterwards can apply grayscaling, as well as edge detection alogrithms to each of the frames.
With the help of friendly stackoverflowers I was able to set up a method capable of converting several images into one video file using ffmpeg-lights' frameWriter function.
Problem
The application runs fine to the moment it hits the frameWriterfunction and I don't really know why as there are no errors or exception-messages thrown. (OS: Win 10 64bit)
What did I try?
I tried..
- different versions of ffmpeg (from 3.2 to 3.4).
- ffmpeg.exe using the command line to test if there are any codecs missing, but any conversion I tried worked.
- different EncodingParams-combinations: like.. EncodingParams width height fps (Nothing) (Nothing) "medium"
Question
Unfortunately, none of above worked and the web lacks on information to that specific case. Maybe I missed something essential (like ghc flags or something) or made a bigger mistake within my code. That is why I have to ask you: Do you have any suggestions/advice for me?
Haskell Packages
- ffmpeg-light-0.12.0
- JuicyPixels-3.2.8.3
Code
{--------------------------------------------------------------------------------------------
Applies "juicyToFFmpeg'" and "getFPS" to a list of images and saves the output-video
to a user defined location.
---------------------------------------------------------------------------------------------}
saveVideo :: String -> [Image PixelYA8] -> Int -> IO ()
saveVideo path imgs fps = do
-- program stops after hitting next line --
frame <- frameWriter ep path
------------------------------------------------
Prelude.mapM_ (frame . Just) ffmpegImgs
frame Nothing
where ep = EncodingParams width height fps (Just avCodecIdMpeg4) (Just avPixFmtGray8a) "medium"
width = toCInt $ imageWidth $ head imgs
height = toCInt $ imageHeight $ head imgs
ffmpegImgs = juicyToFFmpeg' imgs
toCInt x = fromIntegral x :: CInt
{--------------------------------------------------------------------------------------------
Converts a single image from JuicyPixel-format to ffmpeg-light-format.
---------------------------------------------------------------------------------------------}
juicyToFFmpeg :: Image PixelYA8 -> (AVPixelFormat, V2 CInt, Vector CUChar)
juicyToFFmpeg img = (avPixFmtGray8a, V2 (toCInt width) (toCInt height), ffmpegData)
where toCInt x = fromIntegral x :: CInt
toCUChar x = fromIntegral x :: CUChar
width = imageWidth img
height = imageHeight img
ffmpegData = VS.map toCUChar (imageData img)
{--------------------------------------------------------------------------------------------
Converts a list of images from JuicyPixel-format to ffmpeg-light-format.
---------------------------------------------------------------------------------------------}
juicyToFFmpeg' :: [Image PixelYA8] -> [(AVPixelFormat, V2 CInt, Vector CUChar)]
juicyToFFmpeg' imgs = Prelude.foldr (\i acc -> acc++[juicyToFFmpeg i]) [] imgs
{--------------------------------------------------------------------------------------------
Simply calculates the FPS for image-to-video conversion.
-> frame :: (Double, DynamicImage) where Double is a timestamp of when it got extracted
---------------------------------------------------------------------------------------------}
getFPS :: [(Double, DynamicImage)] -> Int
getFPS frames = div (ceiling $ lastTimestamp - firstTimestamp) frameCount :: Int
where firstTimestamp = fst $ head frames
lastTimestamp = fst $ last frames
frameCount = length frames
I suspect issue you are having has something to do with Windows environment and usage of ffmpeg from Haskell (i.e. ffmpeg-simple)
I was able to successfully compile and run your module on Ubuntu 16.04, although I did get a runtime error from ffmpeg:
$ ./main
[NULL # 0x1ea6900] Unable to find a suitable output format for 'foo.avi'
main: Couldn't allocate output format context
CallStack (from HasCallStack):
error, called at src/Codec/FFmpeg/Encode.hs:214:17 in ffmpeg-light-
0.12.0-DYHyy7pUAhZ7WHcd6Y2mLO:Codec.FFmpeg.Encode
It seems like the above error can be fixed with some ffmpeg arguments tweaking, but since that is not the issue you are experiencing I decided not to go any further with debugging it.
Just in case my main:
main :: IO ()
main = do
Right (ImageYA8 img) <- readPng "foo_ya.png"
saveVideo "foo.avi" (replicate 10 img) 10
I ran the same thing on Windows 7 64-bit and it seems I was unable to fully satisfy the dependencies.
Compilation and dependency installation done on Windows:
> stack exec -- pacman -Syu
> stack exec -- pacman -S mingw-w64-x86_64-gtk3
> stack exec -- pacman -S mingw-w64-x86_64-pkg-config
> stack exec -- pacman -S mingw-w64-x86_64-ffmpeg
> stack --install-ghc --resolver lts-9.10 exec --package vector --package JuicyPixels --package ffmpeg-light -- ghc main.hs -O2 -threaded
> stack exec -- main.exe
Results in a popup error when ran in cmd (ps simply exits):
The procedure entry point inflateValidate could not be located in the dynamic link library zlib1.dll
I am no expert on development on Windows, so I feel like I am missing something. Hope my attempt will be at least a little bit helpful.

Xcode + LLDB: trying to change variable value using 'expression'

I am trying to improve my debugging skills, so started reading around here. I have the following piece of code:
var label = "tom"
self.label.text = label
print(label)
I have a break point in each of the lines, and in each of them I type
expression label = "jones"
po label
So, when I type po label I get the expected result, which is jones, but the text presented in the label and the console (from print(label)) is tom.
The tutorial I linked states that the changes should take effect for the entire run of the program. Is it false, or am I doing something wrong?
I am using Xcode Version 8.2.1 (8C1002) with an iPhone 7 Plus simulator.
Thanks!
I'm not sure this helps, but what is going on is a little more complicated than you think.
Swift strings are actually structs, so if you stopped on the line before you assign to self.text.label, and assign a new value to your label var, you are actually changing the contents of the struct, which should by all rights mean that when you assign to self.text.label from that struct, it really should pick up the new value...
The reason that doesn't work is that the swift compiler is smart about unboxing these structs so that it doesn't do unnecessary dereferences when possible. This happens even at -Onone.
So for instance, in your example the swift compiled code has already unboxed the string and emitted code that directly references the contents. Changing the actual string contents doesn't change the references to the unboxed contents already in the assignment code, and so your change doesn't take.
You can see this IRL: if you make the compiler unable to know what the contents of the string are, it can't do this unboxing, and then you will see your debugger changes take effect.
Using this example code:
class HasLabel
{
var label : String = "Default Value"
}
func
main ()
{
var myLabel = HasLabel()
var string = "set in code"
string.removeSubrange(string.startIndex..<string.endIndex)
string.append("Different string in code")
myLabel.label = string // Set a breakpoint here
print ("Did it change? string: \"\(string)\" Label: \"\(myLabel.label)\"")
}
main()
in the debugger, I see:
(lldb) br s -p "Set a breakpoint here"
Breakpoint 1: where = tryme`tryme.main () -> () + 499 at tryme.swift:14, address = 0x0000000100001e93
(lldb) run
Process 8323 launched: '/private/tmp/tryme' (x86_64)
Process 8323 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100001e93 tryme`tryme.main () -> () at tryme.swift:14
11
12 string.removeSubrange(string.startIndex..<string.endIndex)
13 string.append("Different string in code")
-> 14 myLabel.label = string // Set a breakpoint here
^
15 print ("Did it change? string: \"\(string)\" Label: \"\(myLabel.label)\"")
16 }
17
(lldb) expr string = "Set in debugger"
(lldb) c
Process 8323 resuming
Did it change? string: "Set in debugger" Label: "Set in debugger"
Process 8323 exited with status = 0 (0x00000000)
There you see the debugger change actually took. But if you comment out the string.removeSubrange and string.append, then the change will no longer take.

Can you implement OS X's Finder download progress bars from a shell script?

At first I thought this might be some variation on the extended attributes that can be modified with the xattr command line tool. However, I've staged several tests, and the files don't seem to have any special attributes while in this mode.
Is this accessible at all from the command line, or is it only possible from within some cocoa api?
If you don't mind scripting with swift:
#!/usr/bin/env swift
import Foundation
let path = ProcessInfo.processInfo.environment["HOME"]! + "/Downloads/a.txt"
FileManager.default.createFile(atPath: path, contents: nil, attributes: [:])
let url = URL(fileURLWithPath: path)
let progress = Progress(parent: nil, userInfo: [
ProgressUserInfoKey.fileOperationKindKey: Progress.FileOperationKind.downloading,
ProgressUserInfoKey.fileURLKey: url,
])
progress.kind = .file
progress.isPausable = false
progress.isCancellable = false
progress.totalUnitCount = 5
progress.publish()
while (progress.completedUnitCount < progress.totalUnitCount) {
sleep(1)
progress.completedUnitCount += 1
NSLog("progress %d", progress.completedUnitCount)
}
NSLog("Finished")
(Apple Swift version 4.1.2, Xcode 9.4)
Thanks to https://gist.github.com/mminer/3c0fbece956f3a5fa795563fafb139ae
AFAIK, this all occurs through the NSProgress class, a Cocoa API, so getting it to happen from a shell script alone is very unlikely:
https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSProgress_Class/#//apple_ref/doc/constant_group/File_operation_kinds
Here is how Chrome implemented it (newer code probably available):
http://src.chromium.org/viewvc/chrome?revision=151195&view=revision

MATLAB to read in a password

I'm building a MATLAB application that authenticates a user's credentials.
I want to read in his password, and I want to hide his typed credentials somehow.
Some constraints:
I have to account for windows as well as linux/mac users.
I can't be assured of any programs (perl/python/VBS) in the user system.
Here's what I've tried:
Straight-up GUIDE
Works, but not an option as the user is likely to be running matlab in -nodesktop (or -nodisplay) mode.
MATLAB + Java
console.readPassword. This messes up my terminal horribly.
system() calls
Essentially I call bash or dos scripts based on OS.
I have the following call for linux/mac:
[status cred] = system('stty -echo; read cred; stty echo;echo ""; echo "$cred"');
This is supposed to pick up the user credentials and dump that on to 'cred'. I've checked that it works in the regular terminal, but executing it in MATLAB causes nothing to be output, and a Ctrl-C is required to bring back the >> prompt.
MATLAB Perl
The Windows MATLAB packages Perl, as pointed out in comments. I tried the following snippet:
use Term::ReadKey;
use Term::ReadLine;
ReadMode('noecho');
$yesnoline = Term::ReadLine->new("foo");
$pass = $yesnoline->readline();
printf "$pass";
ReadMode('restore');
And then called it as [result status] = perl('my_perl.pl'). Works great on Linux.
On Windows:
res =
GetConsoleMode failed, LastError=|6| at ReadKey.pm line 264.
sta =
9
My searches so far suggest that it's a problem related to the packaged version of perl for windows.
Any idea what's happening in the above approaches?
I suggest that you detect Windows installation (ispc), and handle them differently than Unix-like systems, by creating a MATLAB GUI or something similar..
Here is one possible solution for Windows using .NET Windows Forms from inside MATLAB:
function pass = getPasswordNET()
%# password return value
pass = '';
%# hidden figure used to wait for button press
fig = figure('Visible','off', ...
'IntegerHandle','off', 'HandleVisibility','off');
%# create and show the Windows Forms GUI
[handles,lh] = InitializeComponents();
handles.frm.Show();
%# block execution until figure is closed
waitfor(fig)
%# remove the listeners
delete(lh);
return;
%# create GUI
function [handles,lh] = InitializeComponents()
%# import assembly
NET.addAssembly('System.Windows.Forms');
%# form
frm = System.Windows.Forms.Form();
frm.SuspendLayout();
%# textbox
tb = System.Windows.Forms.TextBox();
tb.Dock = System.Windows.Forms.DockStyle.Fill;
tb.Text = '';
tb.PasswordChar = '*';
tb.MaxLength = 14;
%# button
bt = System.Windows.Forms.Button();
bt.Dock = System.Windows.Forms.DockStyle.Bottom;
bt.Text = 'Submit';
%# setup the form
frm.Text = 'Password';
frm.ClientSize = System.Drawing.Size(250, 40);
frm.Controls.Add(tb);
frm.Controls.Add(bt);
frm.ResumeLayout(false);
frm.PerformLayout();
%# add event listeners
lh(1) = addlistener(bt, 'Click', #onClick);
lh(2) = addlistener(frm, 'FormClosing', #onClose);
%# return handles structure
handles = struct('frm',frm, 'tb',tb, 'bt',bt);
end
%# event handlers
function onClick(~,~)
%# get password from textbox
pass = char(handles.tb.Text);
%# close form
handles.frm.Close();
end
function onClose(~,~)
%# delete hidden figure (to unblock and return from function)
close(fig)
end
end
I tested the above on my machine, and it worked even when MATLAB was started in headless mode:
matlab.exe -nodesktop -noFigureWindows
then called it as:
>> pass = getPasswordNET()
pass =
secret_password
It should be straightforward to do something similar in Java using Swing's JPasswordField
Java getPassword
I haven't yet managed to get the getPassword approach to return the console to the normal state - I'm assuming your code looks something like:
import java.lang.*
cs = System.console()
a = cs.readPassword()
Could you confirm this?
Python solution
If the solution has to be multi-platform, and you don't mind Python being a dependency, I would suggest writing a very simple python script and using this with a Matlab system call, something like
file: usergetpass.py
import getpass
import os
os.sys.stdout.write(getpass.getpass())
then in matlab
[status,pass] = system('python usergetpass.py');
You would then have to (trivially) parse pass though, the actual password is contained on line 3 of pass.
So you could put the above into your own mini matlab function,
function out = getpass()
[status, pass] = system('python usergetpass.py');
out = pass(13:end-1);
Note: I can use this because the password always occurs at that point in the pass variable.

Haskell Graphics Library that works in GHCi on MacOS X

Does there exist a Haskell graphics library or binding to an external library that fulfills the following requirements:
Can be used from ghci, i.e. I don't have to link and restart the program.
Works on MacOS X. (Tricky in conjunction with 1!)
Can do simple vector graphics (lines, polygons, simple fills and strokes).
Can put bitmap images on screen. Example: blit a 17x12 .bmp image.
?
Please include a minimal source code example or a reference to it (just a window on screen, maybe with a green line drawn inside it) so that I can check the points 1. and 2. in particular. Also, if one of these feature requests is more elaborate (for example OpenGL + 4), please include a good reference.
PS: Concerning 1 and 2, I know about the enableGUI trick and I am willing to use it. However, most libraries have the problem that you can't run the main function multiple times and hence don't qualify.
Edit: To avoid wasting your time, here a list of packages that I've tried:
wx - ghci chokes on libstdc++
sdl - redefines main to be a macro. Compile-time only.
GLFW (OpenGL) - Can't run main twice, something about "failing because it can't install mouse event handler".
EDIT: Actually, I'm no longer sure. Several versions later, it seems that GLFW no longer works in GHCi on OS X.
It turns out that GLFW+OpenGL fulfills all four requirements!
You need to invoke ghci with ghci -framework Carbon.
You need the EnableGUI.hs file, which you can get here. Note that you can't load it right into GHCi, you have to comiple it, first.
OpenGL has a 2D projection mode where you can draw lines and polygons.
Bitmaps can be loaded as textures and put on polygons.
Here is a small example that puts a bitmap onto the screen. There are some restrictions on the bitmap: its dimensions must be a power of two (here 256) and it must be a .tga file (here "Bitmap.tga"). But since transparency is supported, this is not much of a problem.
You should be able to call main multiple times without problem. The key point is that you should not call GLFW.terminate.
import Graphics.Rendering.OpenGL as GL
import qualified Graphics.UI.GLFW as GLFW
import Graphics.Rendering.OpenGL (($=))
import Control.Monad
import EnableGUI
main = do
enableGUI
GLFW.initialize
-- open window
GLFW.openWindow (GL.Size 400 400) [GLFW.DisplayAlphaBits 8] GLFW.Window
GLFW.windowTitle $= "Bitmap Test"
-- enable alpha channel
GL.blend $= GL.Enabled
GL.blendFunc $= (GL.SrcAlpha, GL.OneMinusSrcAlpha)
-- set the color to clear background
GL.clearColor $= GL.Color4 0.8 0.8 0.8 0
-- set 2D orthogonal view inside windowSizeCallback because
-- any change to the Window size should result in different
-- OpenGL Viewport.
GLFW.windowSizeCallback $= \ size#(GL.Size w h) ->
do
GL.viewport $= (GL.Position 0 0, size)
GL.matrixMode $= GL.Projection
GL.loadIdentity
GL.ortho2D 0 (realToFrac w) (realToFrac h) 0
render <- initialize
loop render
GLFW.closeWindow
loop render = do
-- draw the entire screen
render
-- swap buffer
GLFW.swapBuffers
-- check whether ESC is pressed for termination
p <- GLFW.getKey GLFW.ESC
unless (p == GLFW.Press) $ do
-- sleep for 1ms to yield CPU to other applications
GLFW.sleep 0.001
-- only continue when the window is not closed
windowOpenStatus <- GLFW.getParam GLFW.Opened
unless (windowOpenStatus == False) $
loop render
-- rendering
initialize = do
-- load texture from file
GL.texture GL.Texture2D $= Enabled
[textureName] <- GL.genObjectNames 1
GL.textureBinding GL.Texture2D $= Just textureName
GL.textureFilter GL.Texture2D $= ((GL.Nearest, Nothing), GL.Nearest)
GLFW.loadTexture2D "Bitmap.tga" []
return $ do
GL.clear [GL.ColorBuffer]
GL.renderPrimitive GL.Quads $ do
GL.texCoord $ texCoord2 0 0
GL.vertex $ vertex3 (0) 256 0
GL.texCoord $ texCoord2 0 1
GL.vertex $ vertex3 (0) (0) 0
GL.texCoord $ texCoord2 1 1
GL.vertex $ vertex3 256 (0) 0
GL.texCoord $ texCoord2 1 0
GL.vertex $ vertex3 256 256 0
-- type signatures to avoid ambiguity
vertex3 :: GLfloat -> GLfloat -> GLfloat -> GL.Vertex3 GLfloat
vertex3 = GL.Vertex3
texCoord2 :: GLfloat -> GLfloat -> GL.TexCoord2 GLfloat
texCoord2 = GL.TexCoord2
color3 :: GLfloat -> GLfloat -> GLfloat -> GL.Color3 GLfloat
color3 = GL.Color3
Here an example bitmap (which you need to convert to .tga).
The Gtk2Hs library fulfills all the requirements if you use the X11 version of the gtk2 framework.
Concerning the requirements:
Using X11 avoids many problems.
Install gtk2 via MacPorts and use the +x11 option (default). (That said, I've had numerous problems installing gtk2 in the past, but this time it seemed to work.)
I would be surprised if GTK+ can't do that.
Ditto.
Here a minimal example
import Graphics.UI.Gtk
hello :: (ButtonClass o) => o -> IO ()
hello b = set b [buttonLabel := "Hello World"]
main :: IO ()
main = do
initGUI
window <- windowNew
button <- buttonNew
set window [windowDefaultWidth := 200, windowDefaultHeight := 200,
containerChild := button, containerBorderWidth := 10]
onClicked button (hello button)
onDestroy window mainQuit
widgetShowAll window
mainGUI
As of early 2014, I wasn't able to use #heinrich-apfelmus answer in Mac OS X. This GLFW-b example (link) however worked.
So, ensure you have:
$ cabal install glfw-b
and, if you tried Apfelmus' answer, you may need to
$ ghc-pkg list
$ ghc-pkg unregister GLFW-x.x.x.x
as both provide Graphics.UI.GLFW, and you will get an "Ambiguous module name 'Graphics.UI.GLFW'" from ghc. Then I just tried the sample program above and it worked (Mac OS X, 10.9, Mavericks)
Have you seen the GLFW as referenced http://plucky.cs.yale.edu/soe/software1.htm
More information on Haskell+GUI+OpenGL is available in this discussion:
http://www.haskell.org/pipermail/haskell-cafe/2011-May/091991.html

Resources