Source

gnome-record-screen / GNOME-Record-Screen / src / Utils.cs

Full commit
/**
 * Utils.cs
 *
 * :copyright: 2008 mitsuhiko.
 * :license: BSD
 */

using System;
using System.Text;
using System.Collections.Generic;
using System.Runtime.InteropServices;

using Gtk;
using Mono.Unix;

namespace Gnome.RecordScreen {
	
	/**
	 * Baseclass for all configuration pane widgets.
	 */
	public class ConfigurationPane : Gtk.Bin {
		
	}
	
	public class Utils {
		private static List<VideoEncoder> availableVideoEncoders;
		
		/**
		 * A list of available video encoders.
		 */
		public static List<VideoEncoder> AvailableVideoEncoders {
			get {
				if (availableVideoEncoders == null) {
					availableVideoEncoders = new List<VideoEncoder> ();
					if (GStreamerInterface.HasEncoder (VideoEncoder.H264))
						availableVideoEncoders.Add (VideoEncoder.H264);
					if (GStreamerInterface.HasEncoder (VideoEncoder.Theora))
						availableVideoEncoders.Add (VideoEncoder.Theora);
					if (GStreamerInterface.HasEncoder (VideoEncoder.Mpeg))
						availableVideoEncoders.Add (VideoEncoder.Mpeg);
				}
				return availableVideoEncoders;
			}
		}
		
		/**
		 * Shows an error message as dialog.
		 */
		public static void ShowError (string title, string message, Gtk.Window parent)
		{
			Gtk.Dialog dialog = new Gtk.MessageDialog (parent, DialogFlags.Modal,
			                                           MessageType.Error,
			                                           ButtonsType.Ok, message);
			dialog.Title = title;
			dialog.Run ();
			dialog.Destroy ();
		}
		
		public static void ShowError (string title, string message)
		{
			ShowError (title, message, null);
		}
		
		/**
		 * Makes sure the rectangle is divisble by two which is required
		 * for some codecs such as H.284.  If the rectangle is too small,
		 * a RectangleTooSmallException() is raised.
		 * 
		 * This function returns a copy of the rectangle if it had to
		 * modify it.
		 */
		public static Gdk.Rectangle RemodelRectangle (Gdk.Rectangle rect)
		{
			int width = rect.Width;
			int height = rect.Height;
			
			if (width % 2 == 1)
				width--;
			if (height % 2 == 1)
				height--;

			if (height < 32 || width < 32)
				throw new RectangleTooSmallException ();
			
			if (width == rect.Width && height == rect.Height)
				return rect;
			
			return new Gdk.Rectangle (rect.X, rect.Y, width, height);
		}
		
		/**
		 * Adds the current date to the filename.
		 */
		public static string AddDateToFilename (string filename)
		{
			string extension = "";
			List<string> parts = new List<string> (filename.Split ('.'));
			if (parts.Count > 1) {
				extension = "." + parts[parts.Count - 1];
				parts.RemoveAt(parts.Count - 1);
				filename = String.Join(".", parts.ToArray ());
			}
			DateTime now = DateTime.Now;
			return String.Format("{0} ({1}-{2}-{3}){4}", filename,
			                     now.Year, now.Month, now.Day,
			                     extension);
		}
		
		/**
		 * Sets the process title for process monitors
		 */
		public static void SetProcessName (string name)
		{
			if (name.IndexOf ('\0') >= 0)
				throw new ArgumentException ("null-bytes in name not allowed");
			try {
				if (prctl (15, Encoding.UTF8.GetBytes (name + "\0"),
				           IntPtr.Zero, IntPtr.Zero, IntPtr.Zero) != 0)
					throw new ApplicationException ("Error setting process name: " +
					                                Mono.Unix.Native.Stdlib.GetLastError ());
			}
			catch (EntryPointNotFoundException) {
				setproctitle (Encoding.UTF8.GetBytes ("%s\0"),
				              Encoding.UTF8.GetBytes (name + "\0"));
			}
		}
		
#region Low-Level Functions
		
		[DllImport ("libc")] // Linux
		private static extern int prctl (int option, byte [] arg2, IntPtr arg3,
		                                 IntPtr arg4, IntPtr arg5);

		[DllImport ("libc")] // BSD
		private static extern void setproctitle (byte [] fmt, byte [] str_arg);

#endregion
	}
}