Tuesday, July 10, 2012

GIMP 2.8 has arrived

GIMP (GNU IMAGE) 2.8 is here.

It just occurred to me the other day that GIMP was working on 2.8. I thought I would like to check it out.  When I got there (www.gimp.org), it is there.

I like the single view mode (under menu Windows, Single-Window-Mode).  It solved the only complaint I had with GIMP in the past. That is to click twice in order to re-focus on the other window when switching between tool/editor/layer windows.

I have not checked out what else is new in it. GIMP is one of a few open source projects I appreciated and used frequently. I would expect to continue creating a lot of digital assets from GIMP for my iPhone app projects.

Friday, March 30, 2012

Combine gmail and Java mail library to create your email compaign

If you use gmail for your company, you can run your own email campaign without paying those email campaign companies.  Write a small script or Java program to pull user data from your database and create a pretty HTML based email template. If you want to track them, insert the tracking in the HTML content.  Use the following code to start sending emails to your users.  Just be sure not to abuse the gmail account.


import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;


public class Mailman extends javax.mail.Authenticator
{
    private String smtpServer;
    private String from;
    private String password;
    private boolean useAuth;


    public Mailman(String sender)
    {
        from = sender;
        smtpServer = "smtp.gmail.com";
    }


    public String getSmtpServer() { return smtpServer; }
    public void setSmtpServer(String svr) { smtpServer = svr; }


    public String getSender() { return from; }
    public void setSender(String fm) { from = fm; }


    public String getPassword() { return password; }
    public void setPassword(String passwd) {
        password = passwd;
        if (passwd != null && passwd.length() > 0) {
            useAuth = true;
        } else {
            useAuth = false;
        }
    }


    /*
     * This method sends plain text mail.
     */
    public void send(String subject, String body, String to, String cc)
    {
        try
        {
            Message msg = createMessage(subject, to, cc);
            msg.setText(body);
            Transport.send(msg);
        }
        catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }


    /*
     * this method sends mail with file attachments
     */
    public void send(String subject, String body, List<String> attachPaths, String to, String cc)
    {
        try
        {
            Message msg = createMessage(subject, to, cc);
            Multipart multipart = new MimeMultipart();
            MimeBodyPart messageBodyPart = new MimeBodyPart();
            messageBodyPart.setText(body);
            multipart.addBodyPart(messageBodyPart);


            for (String fileAttachment : attachPaths) {
                MimeBodyPart attachment = new MimeBodyPart();
                DataSource source = new FileDataSource(fileAttachment);
                attachment.setDataHandler(new DataHandler(source));
                attachment.setFileName(new File(fileAttachment).getName());
                multipart.addBodyPart(attachment);
            }
            msg.setContent(multipart);


            Transport.send(msg);
        }
        catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }


    protected Message createMessage(String subject, String to, String cc) throws Exception
    {
        Properties props = System.getProperties();
        props.put("mail.smtp.host", smtpServer);
        Session session = null;
        if ( useAuth ) {
            props.put("mail.smtp.starttls.enable","true");
            props.put("mail.smtp.auth", "true"); 
            // SSL
            props.put("mail.smtp.socketFactory.port", "465");
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.socketFactory.fallback", "false");


            session = Session.getInstance(props, this);
        } else {
            session = Session.getInstance(props);
        }
        // create a new message
        Message msg = new MimeMessage(session);


        if (from == null) {
          from = System.getProperty("user.name");
        }
        msg.setFrom(new InternetAddress(from));
        msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));
        if (cc != null) {
            msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc, false));
        }


        // set the subjecttext
        msg.setSubject(subject);
        // set some other header information
        msg.setHeader("X-Mailer", "s3ar-JavaMail");
        msg.setSentDate(new Date());


        return msg;
    }


    @Override
    public PasswordAuthentication getPasswordAuthentication()
    {
        // you can read the password from a file
        // which should set mode as 0400


        return new PasswordAuthentication(from, password);
    }
}

Monday, March 26, 2012

Update xcodebuild path

The installation directory of Apple's IDE, Xcode, moved from /Developer to /Applications starting version 4.3.1. It caused some glitches for tools, such as xcodebuild, if invoked as a command-line utility.

To point it to the new installation base, use
sudo /usr/bin/xcode-select -switch /Applications/Xcode.app/

Verify the change with
/usr/bin/xcode-select -print-path

Monday, March 19, 2012

Examine multiple files in command less

To change to the next file after opening multiple files simultaneously in 'less' command, use this command

:n

And to change to the previous file, use

:p


The instruction should also be available from the man page.

Sunday, March 11, 2012

Create symbolic links in Windows 7

I was running XAMPP on Windows 7 and tried to use symbolic link point to the folders with PHP code. The soft link created in Cygwin (ln -s <directory> <link-name>) did not seem to be recognized by Apache. I found  I need to use native Windows command in the command prompt.

Run Command Prompt as administrator
> MKLINK /D <link-name> <target directory>

Note

I tried to use secpol.msc to grant myself with privilege for creating symbolic link.
secpol.msc via Start or Start → Run.
Open Security Settings → Local Policies → User Rights Assignment
It did not give me the permission to create symbolic link even after I re-log in. I have to run the command as administrator.

The chown command equivalent in Windows 7

As 'su - chown' does not work in Cygwin, there is a alternative in Windows 7.
Log in as the user the files should be changed TO and run Command Prompt as administrator.
Run the follow command (or similar one with different parameter combination)

> takeown /F <directory name> /R

Friday, March 9, 2012

Black screen on simulator for iPad retina using cocos2d

I am excited to see that iPad has a retina display. As I am developing my first iPhone/iPad game (universal application) using cocos2d 1.0.1, I updated my Xcode to 4.3.1 to see if my code still works on the new device display.

It showed a black screen.  Nothing displayed.  But the code seems to be running and responding to touch events.  I did not know what happened so I started to search on the web.  I found one posting on cocos2d-iphone forum started a day ago was discussing exactly the same problem.  I read every post and experimented all the proposed solutions.  I don't think it is anything to do with '-hd' image files, as the sample cocos2d HelloWorld did not work in iPad retina display either. But apparently lowering the resolution makes everything work again.  I noticed one member mentioned something particularly interesting, which was about the call to

gluPerspective() in CCDirectorIOS -setProjection()

The call stack is
enableRetinaDisplay => setContentScaleFactor => setProjection, as enableRetinaDisplay is the center of the discussion.

I found that switching to the commented code one line before the now in-use code in CCDirectorIOS makes my code work again in all the simulators.  I posted it to the thread. But here is the complete posting.  Hope this helps you as well.


I was following DonomaGames's post on gluPerspective() (CCDirectorIOS line 212-213).  Line 212 was commented out and replaced with line 213,

gluPerspective(60, (GLfloat)size.width/size.height, 0.5f, 1500);

which has zFar as 1500.  I did a calculation using the formula on 212, zNear=zeye-height/2, zFar=zeye+height/2. On iPad retina, the zFar value is 2794.707275.  It is larger than 1500. The rendering may be clipped off.

For comparison I computed the whole four types.

TypezNear  zFar
iPhone SD   175655
iPhone HD  3501310
iPad SD3731397
iPad HD7462794

Given that, I changed line 212 in CCDirectorIOS.m to
gluPerspective(60, (GLfloat)size.width/size.height, 0.5f, 2800);
It worked for iPad retina simulator.

I also tried the following code and worked also.

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad &&
    [[UIScreen mainScreen] scale] > 1.0 )
{
    gluPerspective(60, (GLfloat)size.width/size.height, zeye-size.height/2, zeye+size.height/2 );
} else {
    gluPerspective(60, (GLfloat)size.width/size.height, 0.5f, 1500);
}

This combines the original 212 and 213 code.

Monday, March 5, 2012

Hostname on Mac OS X

If the dynamic hostname is provided by DHCP, and you prefer a fixed one, there are a few ways to do it.

From System Preferences/Network

  • Select the network adapter which interfaces the DHCP server.
  • Click on the "Advanced" button on the lower right.
  • In the TCP/IP tab, specify the "DHCP client ID" text field.
Or depending on the version of Mac OS:

-- Mac OS X 10.5 and older
On Mac, the hostname shown on the terminal prompt is configured by the file,
/etc/hostconfig. If it is specified as
HOSTNAME=-AUTOMATIC-,
the name shown in the prompt is provided by DHCP or BootP server.

Change that line to
HOSTNAME=(preferred-name)

-- Mac OS X 10.6 and newer
Use the command scutil (system configuration utility)
scutil --set HostName (preferred-name)

Remember to check the name set in
/Library/Preferences/SystemConfiguration/preferences.plist,
under System/System/ComputerName

Thursday, February 23, 2012

Modify grapeConfig.xml to speed up groovy script with @Grab

I had a post on speed up groovy script startup time if Grape @Grab annotation is used in the script.
The cause is described in this post, http://swainya.blogspot.com/2011/09/skip-download-when-groovy-code.html.

The solution described in that post is to add one line in the .groovy/grapeConfig.xml to decrease cache TTL.  Add

<property name="ivy.cache.ttl.default" value="15m"/>

in the <ivysettings> section.

Your grapeConfig.xml will look like this after adding that line


<ivysettings>
  <property name="ivy.cache.ttl.default" value="15m"/>
  <settings defaultResolver="downloadGrapes"/>
......

Friday, January 13, 2012

Show user Library folder in Finder

Since moved to MacOS Lion (10.7.x), the folder Library disappeared from my Finder window.  It bothers me a lot.  Apparently Apple hides it in this OS release.   Here is the way to reveal it.

From console terminal, use this command.

$ chflags nohidden ~/Library/