"Package GLUT does not exist", even though cl-opengl installed in Arch Linux - lisp

I have emacs configured with SLIME for developing in Common Lisp (sbcl) on Arch Linux. The thing is, I now want to start working with OpenGL as well, so I've installed cl-opengl to provide the necessary bindings. I have also set up a symlink on .local/share/common-lisp to /usr/share/common-lisp (I should be able to load all systems using ASDF that way).
However, when I try to compile the following code in SLIME (using C-c C-k)
(require :asdf) ; need ASDF to load other things
(asdf:load-system :cl-opengl) ; load OpenGL bindings
(asdf:load-system :cl-glu) ; load GLU bindings
(asdf:load-system :cl-glut) ; load GLUT bindings
(defclass my-window (glut:window)
()
(:default-initargs :width 400 :height 300
:title "My Window Title"
:x 100 :y 100
:mode '(:double :rgb :depth)))
(defmethod glut:display-window :before ((win my-window))
(gl:shade-model :smooth) ; enables smooth shading
(gl:clear-color 0 0 0 0) ; background will be black
(gl:clear-depth 1) ; clear buffer to maximum depth
(gl:enable :depth-test) ; enable depth testing
(gl:depth-func :lequal) ; okay to write pixel if its depth
; is less-than-or-equal to the
; depth currently written
; really nice perspective correction
(gl:hint :perspective-correction-hint :nicest)
)
(defmethod glut:display ((win my-window))
(gl:clear :color-buffer-bit :depth-buffer-bit)
(gl:load-identity))
(defmethod glut:reshape ((win my-window) width height)
(gl:viewport 0 0 width height) ; reset the current viewport
(gl:matrix-mode :projection) ; select the projection matrix
(gl:load-identity) ; reset the matrix
;; set perspective based on window aspect ratio
(glu:perspective 45 (/ width (max height 1)) 1/10 100)
(gl:matrix-mode :modelview) ; select the modelview matrix
(gl:load-identity) ; reset the matrix
)
(glut:display-window (make-instance 'my-window))
I get the following error:
READ error during COMPILE-FILE:
Package GLUT does not exist.
even though cl-glut.asd exists in /usr/share/common-lisp/systems.
What am I doing wrong?

ASDF:LOAD-SYSTEM doesn't take effect until load time, since it's a plain function. If you want the effect to happen at compile time, you have to wrap it in an eval-when form. But it's better to write a system definition that :depends-on those other systems.

Related

Why is racket passing #<void> to my function instead of the state?

I'm learning Racket, and using the book Realm Of Racket. I reached the point where they show you how to animate an image moving down the window, and then suggest you try modifying it to react to a left or right-arrow key press to move the image sideways.
Seemed simple enough...
#lang racket
(require 2htdp/universe 2htdp/image)
(define WIDTH 500)
(define DX 0)
(define HEIGHT 500)
(define IMAGE .) ; The image doesn't show up here
(define (add3-to-state current-state)
(+ current-state 3))
(define (draw-image current-state)
(place-image IMAGE (+ DX (/ WIDTH 2)) current-state (empty-scene WIDTH HEIGHT)))
(define (state-is-500 current-state)
(>= current-state 459))
(define (set-delta current-state key)
(set! DX (+ DX 10)))
(big-bang 0
(on-tick add3-to-state)
(on-key set-delta)
(to-draw draw-image)
(stop-when state-is-500)
)
When I run this, the image moves downwards as before, but as soon as I hit a key, I get an error...
>=: contract violation
expected: real?
given: #<void>
...in the state-is-500 function.
Anyone able to explain why this is happening? As far as I can see, my function for on-key has the same form as the ones they show in the book.
I tried modifying the state-is-500 function to look like this...
(define (state-is-500 current-state)
(printf "~a\n" current-state)
(>= current-state 459))
...and the output I got was...
102
105
#<void>
...before the error happened.
So it looks like #<void> is being passed to the function, but why?
Thanks
The issue is that big-bang expects the function call on-key to return the new state of the game. You are not retuning anything thus the frameworks reports <void>
Thus if the state does not change the you should just return the input state e.g.
(define (set-delta current-state key)
current-state)
Also this framework and Racket itself makes you want to not mutate variables, that is you don't assign to them, or at least you assign to them only once. Thus set! is not something you should use often.
In this case the state of the app that the book provides is just the vertical distance so is just a single number as shown in add3-to-state. The original state is passed in as the first parameter to big-bang.
The change you have to make is that the current state is not just the up-down movement but also the side to side. This movement shows up as the second parameter to place-image. So you have to have a state that can provide the second and third parameters to that.

AutoCAD (also LT) combox control in plot window, ChooseString not finding printer

I made an AutoHotkey script to print drawings to PDF; however, I am having issues with a particular combobox in AutoCAD's plot dialog box. This combobox allows you to select one of your installed printers or printer configuration files. The printer I want to choose is one of the built-in ones, called "DWG To PDF.pc3". Here is my code snippet that DOESN'T work (it appears to do nothing):
Control , ChooseString , DWG , ComboBox1 , Plot - Model
Additionally, I've tried with and without quotes (it's always hard for me to tell when I need to quote literal text) and the full name -- nothing works. My workaround (temporarily, I hope) is to use Control , Choose , N. This is undesirable as different users may have more or fewer printers installed and this will affect where the desired printer is placed in the list. Here is a snippet of that code:
Control , Choose , 20 , ComboBox1 , Plot - Model
For reference, I have installed AutoHotkey version 1.1.30.01 - November 11, 2018.
What am I missing? Or any suggestions or creative solutions (even from other programming languages)? Thank you!
EDIT:
TL;DR - This is mainly geared for LT.
Full Context - I have full AutoCAD (Mechanical) and use LISP for many tasks. In fact, I've used your (Lee Mac's) tutorials and helpful posts across many forums to get started with it years ago. At my company, we have 27 seats of LT (11 full) where I've set up a company ribbon with SCR files for a few things, including printing. This case is a little different because some of the users need to be able to select a few different pre-configured print options.
Of course, I could make more SCR files for this purpose, but they lack user-error-prevention that AHK can provide. Really, I have a working program with AHK, but it's just short of meeting my standard since there seems to be something goofy going on with just that one particular combobox. So, if someone could steer me towards figuring that out, I would greatly appreciate it.
Firstly, it would be helpful if you could clarify whether the host application is the full version of AutoCAD or the lite version AutoCAD LT, since the former supports full customisation using the AutoLISP, .NET, or ObjectARX APIs (and hence this task is straightforward) whereas the latter does not support customisation, meaning third-party tools (such as AutoHotKey) must be used.
If you have access to the full version of AutoCAD, then the task of plotting to a PDF can be accomplished with an AutoLISP program such as the following:
(defun c:pdfall ( / *error* cmd ctb )
(defun *error* ( msg )
(if ctb (setvar 'ctab ctb))
(if cmd (setvar 'cmdecho cmd))
(if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
(princ (strcat "\nError: " msg))
)
(princ)
)
(setq ctb (getvar 'ctab)
cmd (getvar 'cmdecho)
)
(setvar 'cmdecho 0)
(foreach lay (layoutlist)
(setvar 'ctab lay)
(command
"_.-plot"
"_Y" ;; Detailed plot configuration? [Yes/No]:
"" ;; Enter a layout name <Current-Layout>:
"DWG To PDF.pc3" ;; Enter an output device name:
"ISO full bleed A4 (297.00 x 210.00 MM)" ;; Enter paper size:
"_M" ;; Enter paper units [Inches/Millimeters]:
"_L" ;; Enter drawing orientation [Portrait/Landscape]:
"_N" ;; Plot upside down? [Yes/No]:
"_E" ;; Enter plot area [Display/Extents/Limits/View/Window]:
"_F" ;; Enter plot scale (Plotted Inches=Drawing Units) or [Fit] <1=1>:
"_C" ;; Enter plot offset (x,y) or [Center]:
"_Y" ;; Plot with plot styles? [Yes/No]:
"monochrome.ctb" ;; Enter plot style table name (enter . for none):
"_Y" ;; Plot with lineweights? [Yes/No]:
"_N" ;; Scale lineweights with plot scale? [Yes/No]:
"_N" ;; Plot paper space first? [Yes/No]:
"_N" ;; Hide paperspace objects? [Yes/No]:
(LM:uniquefilename (strcat (getvar 'dwgprefix) lay ".pdf"))
"_N" ;; Save changes to page setup [Yes/No]:
"_Y" ;; Proceed with plot [Yes/No]:
)
)
(setvar 'ctab ctb)
(setvar 'cmdecho cmd)
(princ)
)
;; Unique Filename - Lee Mac
;; Returns a filename suffixed with the smallest integer required for uniqueness
(defun LM:uniquefilename ( fnm )
(if (findfile fnm)
(apply
'(lambda ( pth bse ext / tmp )
(setq tmp 1)
(while (findfile (setq fnm (strcat pth bse "(" (itoa (setq tmp (1+ tmp))) ")" ext))))
)
(fnsplitl fnm)
)
)
fnm
)
(princ)
However, assuming you only have access to the basic AutoCAD LT platform, I would suggest using the command-line version of the PLOT command: -PLOT, so that you only need to supply keyboard input to a predictable sequence of prompts, rather than interacting with a dialog interface which differs depending on the last used settings.
When using the -PLOT command, the sequence of prompts for a Paperspace Layout will be as shown in the AutoLISP program posted above, i.e.:
"_.-plot"
"_Y" ;; Detailed plot configuration? [Yes/No]:
"" ;; Enter a layout name <Current-Layout>:
"DWG To PDF.pc3" ;; Enter an output device name:
"ISO full bleed A4 (297.00 x 210.00 MM)" ;; Enter paper size:
"_M" ;; Enter paper units [Inches/Millimeters]:
"_L" ;; Enter drawing orientation [Portrait/Landscape]:
"_N" ;; Plot upside down? [Yes/No]:
"_E" ;; Enter plot area [Display/Extents/Limits/View/Window]:
"_F" ;; Enter plot scale (Plotted Inches=Drawing Units) or [Fit] <1=1>:
"_C" ;; Enter plot offset (x,y) or [Center]:
"_Y" ;; Plot with plot styles? [Yes/No]:
"monochrome.ctb" ;; Enter plot style table name (enter . for none):
"_Y" ;; Plot with lineweights? [Yes/No]:
"_N" ;; Scale lineweights with plot scale? [Yes/No]:
"_N" ;; Plot paper space first? [Yes/No]:
"_N" ;; Hide paperspace objects? [Yes/No]:
<Your PDF Filename Here>
"_N" ;; Save changes to page setup [Yes/No]:
"_Y" ;; Proceed with plot [Yes/No]:

Setting Both `fullheight` and `width` in Emacs on OS X

I find the default size of the Emacs frame a little too small. From reading around I know that I can set the height and width quite easily with something like the following:
;;; 140 x 60 window size
(setq default-frame-alist '((width . 140) (height . 60)))
Which works great on my external monitor, however it is a litte too big for the laptop display. I can solve the height problem by changing to the follwing:
;;; automatically set the height
(setq default-frame-alist '((fullscreen . fullheight)))
Which sets the frame to be as tall as possible for the current screen. I can't however set the width of the frame if I use this method. Adding (width . 140) to the above alist sets the width to the right value but also sets the height to the default height again.
When I see the frame appear it sets itself to the full height, and then sets the width to the value I requested, and shrinks in height.
I can overcome this problem with the following code:
;;; Full height for the default window
(setq default-frame-alist
'((fullscreen . fullheight)))
;; Set the width in a hook and have all windows inherit
(setq frame-inherited-parameters
'(width height))
(add-hook 'after-init-hook
(lambda ()
(set-frame-parameter nil 'width 140)))
Which uses a hook to set the width of the first frame to the value I want, and then sets all other windows to inherit this value.
This isn't very elegant however, so the question is "how can I accomplish this in a simpler (or less hackish) way?".
If you want to see my exact init.el script, take a look at this gist
TL;DR
How can I set both the width of a frame, and set the frame to be as tall as possible on the current monitor, on OS X? It seems you can't specify (width . 140) and (fullscreen . fullheight) in the default-frame-alist.
I have come up with a solution to this. I explicitly calculate the height of the window rather than relying on (fullscreen . fullheight) to do it for me.
The updated code to set the values for the height and width is quite simple:
;;; Nice size for the default window
(defun get-default-height ()
(/ (- (display-pixel-height) 120)
(frame-char-height)))
(add-to-list 'default-frame-alist '(width . 140))
(add-to-list 'default-frame-alist (cons 'height (get-default-height)))
In this code the subtraction of 120 from the height of the screen makes sure that the height of the window takes into account the height of the dock and the menubar. For correct results you will have to make sure that this code is executed after you have chosen the font face to use, otherwise the computed height value will not be valid.
Placing the height calculation in its own function should allow special casing certain operating systems and versions. This method also has the added advantage that is faster to open the window as it doesn't "animate" the height to the full height value.
The last paragraph of the help text for display-pixel-height is:
For graphical terminals, note that on "multi-monitor" setups this
refers to the pixel height for all physical monitors associated
with DISPLAY. To get information for each physical monitor, use
‘display-monitor-attributes-list’.
What got me to this page is what looks like a bug in the X11 implementation but I'm not sure yet. In any case, display-pixel-height works only often but not always.
Sample output from display-monitor-attributes-list is:
(
(
(geometry 0 0 1920 1080)
(workarea 0 25 1920 1055)
(mm-size 478 268)
(frames #<frame *scratch* 0x14489a030>)
(source . "NS")
)
(
(geometry 192 1080 1512 982)
(workarea 192 1080 1512 950)
(mm-size 301 195)
(frames)
(source . "NS")
)
)
In my case, I have a laptop (bottom entry) and a monitor connected to it (the top entry).
One possible solution would be to go through the list, find the monitor with the largest height and do the computations based upon that height and then at the end also do something like (set-frame-position nil 192 1080) where the two coordinates come from the top and left coordinates (the first two values of geometry and work area of the monitor that has the greatest height.
It appears that the workarea is the more prudent set of values to use.
And to further make a robust solution, a hook should be added to window-configuration-change-hook so that when a monitor is added or removed, things will get updated.
I am currently asking some questions on the Emacs developers mailing list and working on a solution for myself. I plan to return and update this entry when I have a solution that I'm happy with but thought this information may be of use to others as is.
Update:
There is no bug. x-display-pixel-height has various X11 rude facts of life. For more details, see this reply.
The "Frame Layout" node in the info documentation for ELisp as a description of the Inner and Outer Frame along with many other concepts that are pertinent to this question.
Here is my current solution. I have not done the hook yet. I don't claim to know how to program in lisp but this code is working for me.
(defun workarea-height ( monitor )
"MONITOR is an entry from `display-monitor-attributes-list' The
height entry (4th value) of the 'workarea' is returned"
(nth 4 (assoc 'workarea monitor)))
(defun monitor-with-largest-height-helper ( a b )
"Compares the height of the workarea of two monitor entries such as
those contained in the output of `display-monitor-attributes-list'"
(let* ((a-height (workarea-height a))
(b-height (workarea-height b)))
(if (> a-height b-height)
a
b)))
(defun monitor-with-largest-height ()
"Returns the monitor entry from `display-monitor-attributes-list'
with the largest 'workarea' height"
(cl-reduce #'monitor-with-largest-height-helper
(display-monitor-attributes-list)))
(defun largest-monitor-height ()
"Returns the usable height in lines of the largest monitor currently
attached"
(let* ((largest-monitor (monitor-with-largest-height)))
(/ (- (workarea-height largest-monitor)
(- (frame-outer-height)
(frame-inner-height)))
(frame-char-height))))
(defun my-resize-frame-height ()
"Resizes the current frame to the full height of the largest monitor
currently attached."
(interactive)
(set-frame-height nil (largest-monitor-height)))
The other work left to do is to make sure the left and top of the frame are within the area of the largest monitor to the frame will be displayed on that monitor.

How to resize a buffer so it only takes a small part of the screen?

In Emacs how can I resize a buffer so it only takes a small part of the screen ?
Is there any way ?
I would like to have the src taking 70% of the screen and a file manager in the other 30%
Set width of current window on current frame to ~ 70%:
(window-resize nil (- (truncate (* 0.7 (frame-width))) (window-width)) t)
The other windows are shrunk automatically. If you want to adjust more than one it gets more difficult.
As command:
(defun window-resize-to-70-percent ()
(interactive)
(window-resize nil (- (truncate (* 0.7 (frame-width))) (window-width)) t))
Use separate window-manager frames for individual buffers (by default). Automatically shrink-fit the frames to fit the buffer content.
See One-On-One Emacs, in particular, libraries fit-frame.el and autofit-frame.el.

How do I set the size of Emacs' window?

I'm trying to detect the size of the screen I'm starting emacs on, and adjust the size and position the window it is starting in (I guess that's the frame in emacs-speak) accordingly. I'm trying to set up my .emacs so that I always get a "reasonably-big" window with it's top-left corner near the top-left of my screen.
I guess this is a big ask for the general case, so to narrow things down a bit I'm most interested in GNU Emacs 22 on Windows and (Debian) Linux.
If you want to change the size according to resolution you can do something like this (adjusting the preferred width and resolutions according to your specific needs):
(defun set-frame-size-according-to-resolution ()
(interactive)
(if window-system
(progn
;; use 120 char wide window for largeish displays
;; and smaller 80 column windows for smaller displays
;; pick whatever numbers make sense for you
(if (> (x-display-pixel-width) 1280)
(add-to-list 'default-frame-alist (cons 'width 120))
(add-to-list 'default-frame-alist (cons 'width 80)))
;; for the height, subtract a couple hundred pixels
;; from the screen height (for panels, menubars and
;; whatnot), then divide by the height of a char to
;; get the height we want
(add-to-list 'default-frame-alist
(cons 'height (/ (- (x-display-pixel-height) 200)
(frame-char-height)))))))
(set-frame-size-according-to-resolution)
Note that window-system is deprecated in newer versions of emacs. A suitable replacement is (display-graphic-p). See this answer to the question How to detect that emacs is in terminal-mode? for a little more background.
I've got the following in my .emacs:
(if (window-system)
(set-frame-height (selected-frame) 60))
You might also look at the functions set-frame-size, set-frame-position, and set-frame-width. Use C-h f (aka M-x describe-function) to bring up detailed documentation.
I'm not sure if there's a way to compute the max height/width of a frame in the current windowing environment.
Taken from: http://www.gnu.org/software/emacs/windows/old/faq4.html
(setq default-frame-alist
'((top . 200) (left . 400)
(width . 80) (height . 40)
(cursor-color . "white")
(cursor-type . box)
(foreground-color . "yellow")
(background-color . "black")
(font . "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1")))
(setq initial-frame-alist '((top . 10) (left . 30)))
The first setting applies to all emacs frames including the first one that pops up when you start. The second setting adds additional attributes to the first frame. This is because it is sometimes nice to know the original frame that you start emacs in.
Try adding the following code to .emacs
(add-to-list 'default-frame-alist '(height . 24))
(add-to-list 'default-frame-alist '(width . 80))
The easiest way I've found to do that in an X-Window environment is through X resources. The relevant part of my .Xdefaults looks like this:
Emacs.geometry: 80x70
You should be able to suffix it with +0+0 location coordinates to force it to the upper-left corner of your display. (the reason I don't do it is that I occasionnally spawn new frames, and it makes things confusing if they appear in the exact same location as the previous one)
According to the manual, this technique works on MS Windows too, storing the resources as key/value pairs in the registry. I never tested that. It might be great, it might be much more of an inconvenience compared to simply editing a file.
You can also the -geometry parameter when firing up emacs: emacs -geometry 80x60+20+30 will give you a window 80 characters wide, 60 rows high, with the top left corner 20 pixels to the right and 30 pixels down from the top left corner of the background.
On ubuntu do:
(defun toggle-fullscreen ()
(interactive)
(x-send-client-message nil 0 nil "_NET_WM_STATE" 32
'(2 "_NET_WM_STATE_MAXIMIZED_VERT" 0))
(x-send-client-message nil 0 nil "_NET_WM_STATE" 32
'(2 "_NET_WM_STATE_MAXIMIZED_HORZ" 0))
)
(toggle-fullscreen)
On windows, you could make emacs frame maximized using this function :
(defun w32-maximize-frame ()
"Maximize the current frame"
(interactive)
(w32-send-sys-command 61488))
(setq initial-frame-alist
(append '((width . 263) (height . 112) (top . -5) (left . 5) (font . "4.System VIO"))
initial-frame-alist))
(setq default-frame-alist
(append '((width . 263) (height . 112) (top . -5) (left . 5) (font . "4.System VIO"))
default-frame-alist))
(defun set-frame-size-according-to-resolution ()
(interactive)
(if window-system
(progn
;; use 120 char wide window for largeish displays
;; and smaller 80 column windows for smaller displays
;; pick whatever numbers make sense for you
(if (> (x-display-pixel-width) 1280)
(add-to-list 'default-frame-alist (cons 'width 120))
(add-to-list 'default-frame-alist (cons 'width 80)))
;; for the height, subtract a couple hundred pixels
;; from the screen height (for panels, menubars and
;; whatnot), then divide by the height of a char to
;; get the height we want
(add-to-list 'default-frame-alist
(cons 'height (/ (- (x-display-pixel-height) 200)
(frame-char-height)))))))
(set-frame-size-according-to-resolution)
I prefer Bryan Oakley's settings. However the 'height not work properly in my GNU Emacs 24.1.1.