Found out about a nice new command - chvt. I am using Synergy these days instead of my KVM (something that will be the subject of another, much longer post), which doesn't send Ctrl-Alt-Fn to the client machines. Which normally isn't a problem, because it only works if you are running X, so it wouldn't work anyway from a virtual terminal.
But in this case, it is a virtual machine running Arch Linux (the Synergy client machine is running Windows 7), so changing virtual terminals would be fine. So I needed to find a way to change virtual terminals besides using the Ctrl-Alt-Fn keystrokes.
Enter the 'chvt' command. It needs to be run as the superuser, so issuing this command swaps the virtual terminal to terminal 2:
$ sudo chvt 2
So now I can swap virtual terminals in virtual machines even if I can't get the fancy keystrokes to go through to them.
I was looking into getting a little more random for my wallpaper and decided to write a quickie little commandline to get a couple new random pictures from my wallpaper directory. Looking at how the conkyPhotoRandom script from conky-colors does it, I came up with:
The cool part of this is the shuf command, which I didn't know about (or, just as likely, knew but forgot about). So this feeds a list of files from my wallpaper folder and randomly chooses two of them. I use 2 because I have 2 monitors, each displaying 1920x1080 and the 'feh' command takes two files and scales them for my background. Maybe I'll just set this as an alias and do it whenever I think of it.
Edited: Of course, you have to take into account spaces in the filenames. So I had to add the various options that use \0 as a line delimiter, rather than \n. In this case, -print0 tells find to end each line with a \0, -z tells shuf the lines end in \0, as does the -0 option for xargs.
I decided to try a new window manager [1], just because I hadn't wasted enough time on just fiddling with Conky [2]. I'm not really into a tiling window managers, even though I have plenty of display space (2 1920x1080 monitors). I had been reading in the Arch forums about GOOMWWM [3] (Get Out Of My Way Window Manager) and looking at the goomwwm web page for it[4] made me think that despite its newness, it looked relatively complete, especially with Xinerama [5] support for my dual monitor setup. So I decided to give it a try.
Trying a new window manager isn't really that big a deal, especially if you are like me and are lazy hardcore enough to not bother to install a login manager like SLiM and just log in to a text terminal and type startx to bring up X. You just change the window manager that gets exec'd at the end of your .xinitc script to be the one you want. So I changed
and off I went! To be honest, I'm not really sure (a) what the "ck-launch-session dbus-launch" part of the command does or (b) if I really need it (as I just copied it from the openbox Arch wiki page), but I left it in there for safety's sake.
But with nothing set up, it merely brings you to a blank, black screen. And, as I didn't have 'dmenu' [6] installed (it should be, I think, at least an optional dependency, as it is prominently featured in the GOOMWWM tutorial [7]), I couldn't really do anything!
So I went back to the command line and installed dmenu and followed the tutorial, and lo, it was good. Window control is a little more painful with the mouse as you have to hold down the Mod key (left Windows key by default) but is a snap with the keyboard, so that's okay. The concept of tags for windows that correspond to desktops in other window managers again takes some getting used to but works very well in practice. It's especially nice to be able to bring up a window on another "desktop" by merely clicking on it.
So then I spent way too much time getting things somewhat customized. I still like blue for a desktop color, so I went over to The Paper Wall to find a few interesting wallpapers and settled on a blue forest [8] as my left desktop and a nice waterfront view of Boston [9] as my right desktop.
Then I went a Conky customizing, which is an endless time sink if there ever was one. Luckily, I discovered this great Conky customizing script called 'conky-colors' [10]. Basically, you pass in a few (or more!) parameters and it creates a stock Conky config file with support scripts and everything. I eventually settled on this for a conky-colors command line:
And then I modified away, mostly to just get the right colors (more blue!). That's the panel on the left side of the right hand screen. It shows system info, a calendar and clock, a random picture from a folder, what my media player (Clementine) is currently playing, and some more system stats.
Then I finally found a script that generated a good Conky weather forecast pane in conkywx[11]. There were a few bumps in the road, but I got them ironed out with the help of the author in the Arch forums and now I have a nice weather panel in the lower right.
So now I just need to get used to goomwwm. I like being able to quickly and easily use the keyboard to move and resize the windows, and even fill the blank space. It can behave a little like a tiling window manager, with commands for windows to swap position, share a position, etc, which I haven't played with much.
It also has a unique idea about "desktops". You can tag any window with a number between 1 and 9 and then hit Alt-F[1-9] to bring all those windows with that tag number to the front. The others are still there but just behind. So it is easy to assign windows to different tags and swap between them, but you can also use very easily use windows with other tags by just clicking on them. And goomwwm tells other tools (like Conky) that the tag selected is the "desktop". Works pretty well.
So I had a hard drive disaster last week. This came hard on the heels of my 14 month old video card biting the dust. I should have know there was something up, when my Windows installation went belly up. I had been getting tons of errors whenever my Arch boot would do a fsck, but I still soldiered on.
And then my video card died. First X Windows on Arch would freeze when I tried to run it, then even Windows started getting weird artifacts and tears, until finally it just would boot into 640x480 256 color mode. Do you even remember how ugly that is?
So I bought a new nVidia EVGA 560ti card. My EVGA 560 was just past the warranty - 14 months (although it sure felt like less). I wanted to upgrade a little bit but I surely didn't need cutting edge, so I went with the 560ti. I like the 560 - it seems to be powerful enough to play the most recent games, yet only requires one slot and no funky power options necessary.
But I broke Windows somehow. Soon I got the dreaded "black screen of death" (bet you didn't know there was one of those) where it boots but then after the splash screen goes away, it just shows black. And even a Microsoft MVP says you might have to reinstall Windows to fix it.
And I tried everything to fix my Windows install, all to no avail. But as I only have Windows 7 installed to play games, and the games are all installed on another partition (and these days, most save games are actually in the cloud, esp. for Steam), I figured it wouldn't be a big deal to reinstall Windows. Just start over, which is always a good idea with Windows anyway.
So I reinstalled Windows and got everything set back up. Takes forever to install, and forever to download all the patches (and it doesn't recognize my r8169 Gigabit Ethernet card out of the box either, so I had to go on a quest for my motherboard's device CD). But I finally got it set up and working.
But of course then I had to get back into Arch as Windows loves to overwrite the boot sector. But by now I am getting pretty good at reinstalling GRUB and using the standard Grub 0.9 commands:
and I was back into Arch. I was finally back in business.
Until about a week later, when I started getting really weird hard drive errors and then BAM! the hard drive just wouldn't boot. This is a 120gb SSD drive that was bought the same time as my video card when I built my new system. And it too was deader than a doornail.
Ugh. But again, I was pretty safe because my /home was on another partition and really, the only thing on the SSD were my two OS partitions, one for ArchBang and one for Windows 7. Which I had, of course, just finished reinstalling and getting setup last week :(
So I decided enough with the "cutting edge" SSDs. I needed a hard drive and I needed it now, so my choices were to buy another 120gb SSD hard drive for $140 or buy a 1TB "green" hard drive for $80. I just couldn't see forking over an extra $60 for an SSD that had about 1/10 the space (although I really didn't need to space as I have a 2tb drive already in there). So I went with the big old technology.
I opened up the case and pulled out the dead SSD. And it was then I noticed what perhaps is the culprit for my dead hardware - 2 of the 3 case fans were not running. I hadn't noticed them when I put together my new computer in the very nice Cooler Master tower I have and thus didn't plug them in. And it is rather warm in the summer down here in my nearly windowless lair, which also wouldn't help.
So I got my fans plugged in and my hard drive hooked up and settled down to another install fest.
I've been doing a lot of ffmpeg programming lately and have been finding it extremely painful. There just isn't much for help out there, certainly no real documentation for using the viatal avcodec library.
'dranger' has about the only comprehensive tutorial around and it's showing its age at this point. There's a few newer notes about updating it, but even those don't cover the latest libavcodec API changes. So I figured I would throw out my version of the first tutorial file, tutorial01.c. The most important change is replacing the long excised img_convert call with the sws_scale call (which also requires creating the SwsContext object). I also just tweaked a couple of the calls to remove any deprecated API calls.
// tutorial01.c
// Code based on a tutorial by Martin Bohme (boehme@inb.uni-luebeckREMOVETHIS.de)
// Tested on Gentoo, CVS version 5/01/07 compiled with GCC 4.1.1
// A small sample program that shows how to use libavformat and libavcodec to
// read video from a file.
//
// Use
//
// gcc -o tutorial01 tutorial01.c -lavformat -lavcodec -lz
//
// to build (assuming libavformat and libavcodec are correctly installed
// your system).
//
// Run using
//
// tutorial01 myvideofile.mpg
//
// to write the first five frames from "myvideofile.mpg" to disk in PPM
// format.
#include
#include
#include
#include
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
FILE *pFile;
char szFilename[32];
int y;
// Open file
sprintf(szFilename, "frame%d.ppm", iFrame);
pFile=fopen(szFilename, "wb");
if(pFile==NULL)
return;
// Write header
fprintf(pFile, "P6\n%d %d\n255\n", width, height);
// Write pixel data
for(y=0; ydata[0]+y*pFrame->linesize[0], 1, width*3, pFile);
// Close file
fclose(pFile);
}
int main(int argc, char *argv[]) {
AVFormatContext *pFormatCtx=NULL;
int i, videoStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVFrame *pFrameRGB;
AVPacket packet;
int frameFinished;
int numBytes;
uint8_t *buffer;
struct SwsContext *img_convert_ctx;
int frameCount=0;
if(argc < 2) {
printf("Please provide a movie file\n");
return -1;
}
// Register all formats and codecs
av_register_all();
// Open video file
if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)
return -1; // Couldn't open file
// Retrieve stream information
if(av_find_stream_info(pFormatCtx)<0)
return -1; // Couldn't find stream information
// Dump information about file onto standard error
av_dump_format(pFormatCtx, 0, argv[1], 0);
// Find the first video stream
videoStream=-1;
for(i=0; inb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {
videoStream=i;
break;
}
if(videoStream==-1)
return -1; // Didn't find a video stream
// Get a pointer to the codec context for the video stream
pCodecCtx=pFormatCtx->streams[videoStream]->codec;
// Find the decoder for the video stream
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL) {
fprintf(stderr, "Unsupported codec!\n");
return -1; // Codec not found
}
// Open codec
if(avcodec_open(pCodecCtx, pCodec)<0)
return -1; // Could not open codec
// Allocate video frame
pFrame=avcodec_alloc_frame();
// Allocate an AVFrame structure
pFrameRGB=avcodec_alloc_frame();
if(pFrameRGB==NULL)
return -1;
// Determine required buffer size and allocate buffer
numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
pCodecCtx->height);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
// Assign appropriate parts of buffer to image planes in pFrameRGB
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
// of AVPicture
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
pCodecCtx->width, pCodecCtx->height);
int w = pCodecCtx->width;
int h = pCodecCtx->height;
img_convert_ctx = sws_getContext(
w,
h,
pCodecCtx->pix_fmt,
w,
h,
PIX_FMT_RGB24,
SWS_BICUBIC,
NULL,
NULL,
NULL);
// Read frames and save first five frames to disk
i=0;
while(av_read_frame(pFormatCtx, &packet)>=0) {
// Is this a packet from the video stream?
if(packet.stream_index==videoStream) {
// Decode video frame
int len = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
if ( len < 0 )
{
fprintf(stderr, "Problems decoding frame\n");
return 1;
}
fprintf(stderr, "len = %d\n", len );
// Did we get a video frame?
if(frameFinished) {
++frameCount;
fprintf(stderr, "Saving frame %d\n", frameCount);
#if 0 // this is the old code
img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24,
(AVPicture*)pFrame, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height);
#else
sws_scale(
img_convert_ctx,
(const uint8_t* const*)pFrame->data,
pFrame->linesize,
0,
pCodecCtx->height,
pFrameRGB->data,
pFrameRGB->linesize);
#endif
// Save the frame to disk
if(++i<=5)
SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height,
i);
}
}
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}
// Free the RGB image
av_free(buffer);
av_free(pFrameRGB);
// Free the YUV frame
av_free(pFrame);
// Close the codec
avcodec_close(pCodecCtx);
// Close the video file
av_close_input_file(pFormatCtx);
return 0;
}
One of the main reasons I was looking for a launch bar was that I created a menu for all my DOS games, using mygtkmenu. Once you create this menu, it just cries out for somewhere to attach it, and wbar fits the bill perfectly.
I have a bunch of old DOS (redundant much?) games that I decided to install. In addition to the ones I own (including the priceless Definitive Wargame Collection), the wonderful Good Old Games site ships several of theirs using DOSBox and even Steam uses it for classics like "X-COM : UFO".
First I would create a short script file to run the game. Due to a bug in the X.org driver, it required a work around; namely, telling SDL (the library used by DOSBox) to not "DGA" mouse (or draw directly to video memory). It seems to be fixed so i took it out.
#! /bin/bash
#export SDL_VIDEO_X11_DGAMOUSE=0
cd /mediax/games/MAGIC
dosbox -conf dosbox.conf
Then I would either grab a screenshot from the game (using Ctrl-F5) or search the web for an icon. And then edit my gamemenu.xml file and add an entry like this:
item = Complete Games Menu cmd = "/home/jdarnold/bin/wargames" icon = /home/jdarnold/icons/CompleteWargameCollection.jpg
item = Decisive Battles of the Civil War cmd = /home/jdarnold/bin/wargame1 ACW DB.EXE icon = /home/jdarnold/icons/DecisiveBattles.png
So I've created a sub-menu off the main menu and I pass in the sub-directory and the executable for the app. In a later installment, I'll talk a little more about DOSBox, which is a really nice program. Here's a couple of shots of the final product:
Recent Comments