Apple 타블렛은 “촉각 피드백 기능”이 추가?
KISTI 『글로벌동향브리핑(GTB)』 2010-01-14
美 Apple의 타블렛에 관한 소문이 12월 23일(미국 시간), 다양한 미디어에서 일제히 나오기 시작했다. 「New York Times」의 라이터인 Nick Bilton씨는 이번 소문에 대해 Apple 스탭의 발언을 소개해 주고 있다.

“신제품에 대해서는 아무것도 말할 수 없습니다만, Steve Jobs씨가 새로운 타블렛에 대해 상당히 마음에 드는 것 만 말할 수 있습니다”라고 Apple의 시니어 사원이 말했다고 한다. Bilton씨는 최근 同사를 떠난 사원이 “새로운 타블렛을 사용할 때 매우 놀랄 것이다”라고 말했다고 한다. 특히 두 번째의 발언에 관심이 집중된다. 사용할 때 인터페이스에서 놀란다고 하면 그건 무슨 말일까? Apple은 2008년 8월에 손 터치와 제스추어 등 2가지를 동시에 감지하는 장치에 대한 특허를 신청한 바 있다. 하지만, 이것은 “놀란다”라고 까지는 말할 수 없다.

흥미로운 것은 「AppleInsider는 美 특허 상표청이 이번 주 새로운 특허 출원이 공개되었다고 한다(http://www.appleinsider.com/articles/09/12/24/possible_apple_tablet_multi_touch_tactile_keyboard_detailed.html).
Apple이 신청한 이 특허 출원(http://appft1.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&Sect2=HITOFF&u=%2Fnetahtml%2FPTO%2Fsearch-adv.html&r=1&f=G&l=50&d=PG01&p=1&S1=20070247429&OS=20070247429&RS=20070247429 )은 “Keystroke tactility arrangement on a smooth touch surface(매끄러운 터치 스크린상에 키스트로크(keystroke) 촉감의 설정)”이라는 제목이다. 기기 표면상의 키보드(터치 스크린상의 가상 키보드)의 촉각 피드백 기구에 대해 쓰여져 있다. 유저가 키의 감촉을 물리적으로 느낄 수 있도록 만들어 진다고 한다.

모두 또는 대부분의 키에 닷(Dots), 바, 또는 그 외의 촉각 피드백 기능을 만드는 것이다. 이의 형태에 대해서 스크린 표면이 입력 모드로 사용되고 있는 경우에는 확대되고, 스크린 표면이 포인팅 모드 등 다른 일부의 모드로 사용되고 있는 경우에는 분절형 프레임(articulating frame)이 설치될 가능성이 있다. 분절형 프레임은 키 범위의 경계가 정해져 키의 윤곽을 나타내거나, 키 범위내에 촉각 피드백 기능이 추가될 가능성이 있다. 게다가 물리적인 키의 표면을 구현하는 형태로 움푹한 곳이 스크린 표면에 나타나는 분절형 프레임이 구성될 가능성도 있다. 다른 형태를 생각해보면, 고정되어 분절적이지 않은 프레임이 스크린 표면 아래에 설치될 가능성이 있다. 이것으로 유저는 누른 곳이 키의 중심에서 떨어져 있으면 큰 저항을 느끼고 키의 중심에서는 작은 저항을 느끼게 된다.

이로써, 키보드를 응시하면서 입력할 필요가 없어진다면 환영해야 할 추가 기능이라고 말할 수 있을 것이다. 게다가, 화면이 큰 터치 스크린의 디바이스에서는 이것이 매우 중요한 기능인 것은 충분히 상상할 수 있다.

Apple은 2009년 7월에도 촉각 피드백 등의 특허를 신청하고 있다. 여기에서는 iPhone에 적용될 가능성이 있는 새로운 기능의 힌트가 있다. 그 중에서도 흥미로운 것은 촉감을 만들어 내는 촉각 피드백에 관한 특허다. 누르고 있는 터치 스크린상의 가상 키를 감지하는 것이 가능하다는 것이다. 촉각 피드백 아이디어는 다음과 같다. iPhone의 진동에 의해 물리 키보드에서 느끼는 진동을 시뮬레이트하는 것으로 타이핑중에 각 키의 진동을 느끼는 것이 가능하다는 것이다. 이것이 실현되면 입력중에 화면을 볼 필요가 없어진다.
출처 : http://www.wired.com/gadgetlab/2009/12/apple-tablet-surprise/

넥슨별 레벨업!!!!

녹녹하지만은 안네.....

별사람이란....










'사이버탐험기' 카테고리의 다른 글

저랩의 와우이야기1  (0) 2010.01.23
넥슨의 별나라 이야기!!!!!  (0) 2010.01.23
넥슨별 생활이란....  (0) 2010.01.10
꿈의 별! 넥슨별!  (0) 2010.01.03
IMVU 라는 인터넷 데이트 장소  (0) 2010.01.03
Introducing Calculon – a Java DSL for Android Activity testing PDF Print E-mail

I have been working on a new test library for Google Android lately, a project which I’m very excited about, and which I feel has loads of potential: Calculon, an Android testing library which lets you write functional tests for your Activities using a very concise and natural syntax.

I am a big fan of test-driven development, and I think there’s no arguing about the massive benefits you get from backing your software up with an automated test suite. The support for writing tests in Android, however, is lacking at best. Even though there has been a test runner since the 1.0 days, writing unit or functional tests in Android is far from being a pleasant experience. For me, the two most important things about tests are that they must be easy to write, and more importantly, easy to read.

That being said, here is a classic example of why Android testing sucks. Our test story is:

Assert that a click on ‘button’ launches a new BarActivity.

Without Calculon, what you do is this:

01public void whatInHeavensNameDoesThisEvenTest() {
02 final Button b = (Button) getActivity().findViewById(R.id.button);
03 ActivityMonitor monitor = getInstrumentation().addMonitor(
04 BarActivity.class.getCanonicalName(), null, false);
05 getInstrumentation().runOnMainSync(new Runnable() {
06 public void run() {
07 b.performClick();
08 }
09 });
10 getInstrumentation().waitForIdleSync();
11 assertTrue(getInstrumentation().checkMonitorHit(monitor, 1));
12}

So, I first have to retrieve a reference to the button that’s supposed to launch a new BarActivity. Then I have to create what Android calls an ActivityMonitor, that’s simply an object which just sits there and waits until an Activity is being launched that matches the description it was configured with. Then I have to perform the actual button click, but sorry, not allowed on the instrumentation thread, so I have to runOnMainSync(). We’re not yet there though: we have to sit and wait, because launching a new activity could take a while, so we also have to waitForIdleSync(). The assertion that follows also couldn’t be less expressive.

When I first wrote this test, my single thought was: Where the heck is my story? It’s buried under a heap of ugly boilerplate code.

I don’t care that the test runner cannot perform a view event on the instrumentation thread. I don’t care that it needs to sit and wait for the Activity to launch. I don’t care about ActivityMonitor and its crummy API. I just want to look at the test, and understand what it’s doing.

Let’s reiterate our test story:

Assert that a click on ‘button’ launches a new BarActivity.

With Calculon, this test is written as:

assertThat(R.id.button).click().starts(BarActivity.class);

Oh the beauty. Our test story was a single sentence, so is the test. That’s how it should be, really. There’s nothing worse than seeing someone else’s tests failing on the build server and having to dissect them line by line to figure out what it’s actually testing.

So let’s move on and look at some nifty Calculon tests. And remember: “Calculon never does two takes!”

Testing with Calculon

Calculon is in a very early stage of development, and currently it only supports writing functional Activity tests, using Android’s ActivityInstrumentationTestCase2. Here is what a Calculon test looks like:

1public class FooTest extends FunctionalTest<FooActivity> {
2 public FooTest() {
3 super("com.example", FooActivity.class);
4 }
5
6 public void testStuff() {
7 ...
8 }
9}

Nothing special here, really. You just inherit from a Calculon FunctionalTest.

Assertions

At the heart of a Calculon test are assertions. To create a new assertion, you use the assertThat() method:

01public void testStuff() {
02 // testing against activities
03 assertThat()...
04 assertThat(getActivity())...
05 assertThat(someOtherActivity)...
06
07 // testing against views
08 assertThat(R.id.some_button)...
09 assertThat(someButton)...
10
11 // of course all Junit assertions work as well
12 assertEquals(...)
13 assertNotNull(...)
14 ...
15}

For now, there are two basic kinds of assertions: ActivityAssertion and ViewAssertion. There is also a third kind, ActionAssertion, but it takes a somewhat special role and is discussed at the end.

Activity Assertions

An ActivityAssertion is an assertion on the state of an Activity and is used like this:

01public void testStuff() {
02 // testing for an orientation
03 assertThat().inPortraitMode();
04
05 // testing for views
06 assertThat().viewExists(R.id.some_button);
07
08 // testing for input actions
09 assertThat().keyDown(KeyEvent.KEYCODE_BACK)...
10
11 // testing for custom predicates
12 assertThat().satisfies(new Predicate<Activity>() {
13 public boolean check(Activity target) {
14 return target.isTaskRoot();
15 }
16 });
17}

View Assertions

A ViewAssertion is basically the same, just that it tests the state and behavior of a view:

01public void testStuff() {
02 // testing for view state
03 assertThat(R.id.button).isVisible();
04 assertThat(R.id.button).isGone();
05
06 // testing for input actions
07 assertThat(R.id.button).keyDown(KeyEvent.KEYCODE_BACK)...
08 assertThat(R.id.button).click()...
09 assertThat(R.id.button).longClick()...
10
11 // testing for custom predicates
12 assertThat(R.id.button).satisfies(new Predicate<View>() {
13 public boolean check(View target) {
14 return target.getVisibility() == View.VISIBLE;
15 }
16 });
17}

Action Assertions

This is a special kind of assertion. You always use it when you want to assert that some action (e.g. a click or a key press) does something. You can use it on both activity and view assertions, and it also allows you to delegate an assertion to another object:

01public void testStuff() {
02 // testing for actions that launch a new activity
03 assertThat(R.id.b1).click().starts(BarActivity.class);
04
05 // testing for actions that finish an activity
06 assertThat(R.id.b2).keyDown(KeyEvent.KEYCODE_Q).finishesActivity();
07
08 // testing for actions that change something
09 assertThat(R.id.b3).click().implies(R.id.b2).isGone();
10 assertThat(R.id.b4).click().implies(getActivity()).inLandscapeMode();
11 assertThat(R.id.b5).click().implies(new Predicate<Model>() {
12 public boolean check(Model target) {
13 return target.someAttribute() == 5;
14 }
15 });
16}

There’s more to come!

This is only a very early version. I intend to expand this library significantly over time. Of course it’s open source, so contributions are always welcome. You can fork the project on GitHub, add your changes, and send me a pull request.

Source: brainflush

Beginner iPhone SDK Hello World Tutorial [Example & Code]

Posted by Adeem Basraa On July - 3 - 2009
New in iPhone Development? You can now follow this blog on google readers or subscribe for email or Twitter!
If my tutorial help you then please donate, so that i continue writing free tutorials for every developer/programmer/freelancer

Introduction:

I am going to show you the simplest way to create hello world iPhone tutorial. I will write few more tutorials on the basic of iPhone Development. So this tutorial is an absolute beginner guide for iphone development. To get start with iPhone development you need to have iPhone SDK which you can get from here (http://developer.apple.com/iphone). To download it you need to have a apple developer account which is free for everyone. To test the code on device (iPhone) you need to buy a developer license which cost you 99$ or 299$ for enterprise.

Getting Started with iPhone Development:

To start with hello world iPhone tutorial, you should read the “getting started with iPhone” tutorial which covers the things you need to know before starting development for iPhone( You can also watch the video tutorial of “Getting Started with iPhone” ). I also write a tutorial for businessman and designer to know about the iPhone development cycle (”iPhone Development Guide” ). So if you are a beginner for iPhone, you should read my tutorial before starting iPhone development.

Idea of this tutorial:

There are already many tutorials on hello world in iPhone but I want to write a very basic tutorial on iPhone sdk which will cover xcode, iphone project files and interface builder. This is a basic hello world tutorial which will be extended to a big project later on. So before reading other tutorials on my blog I highly recommended you to read this beginner’s Guide to iPhone development. OR you can watch the video tutorial here if you have no time to follow easy steps :) .

Final output of hello world tutorial

customize UITableView using UITableViewCell
Hello world iPhone tutorial Output

Simple Steps to create hello world iPhone application

Step 1:If you have read the getting started tutorial, then you have a xcode installed on your mac machine. Open the Xcode and click on File > New Project. Select “View-Based Application” and click on “Choose..” button. Name this project “Hello World” and click “Save” button. Now you have a template for your hello world iphone project.

customize UITableView using UITableViewCell
Create a new Xcode Project for iPhone application

customize UITableView using UITableViewCell
Select the basic design for your first iPhone application

customize UITableView using UITableViewCell
Name your first iPhone applcation

customize UITableView using UITableViewCell
Xcode project template created

Step 2:Now click on Build and Go button to run this template application. It will start the iPhone simulator and you can see a gray screen on that. Click on Home button and it will show you a HelloWorld icon on the dash board of iPhone simulator. If you click on it again, it will open the application again. iPhone simulator is best tool to test your application before you deploy it on your device for testing or even before submitting to apple store.

customize UITableView using UITableViewCell
Build your First iPhone application

customize UITableView using UITableViewCell
Output of your first iPhone application
customize UITableView using UITableViewCell
Press this button to quit your first iPhone application

Step 3:Now open Xcode project and select HelloWorldViewController.h file and type the following code inside interface:

IBOutlet UITextField *txtUserName;
IBOutlet UILabel *lblUserTypedName;
Also write this method before end of this class
- (IBAction) submitYourName;


Step 4:So your HelloWorldViewController.h file will look like this:

#import <UIKit/UIKit.h>

@interface HelloWorldViewController : UIViewController {
IBOutlet UITextField *txtUserName;
IBOutlet UILabel *lblUserTypedName;
}

- (IBAction) submitYourName;
@end

Step 5:Now open HelloWorldViewController.m file and type this method before @end
- (IBAction) submitYourName;{
lblUserTypedName.text = txtUserName.text;
}

Step 6:Now lets start some design on interface builder. For that open your xcode project and in “Group & Files” looked at bottom, you will see “NIB Files”, expand it and you will see two design files for your classes. One is the MainWindow.xib which is the main window or entry point to your application. Other one is HelloWorldViewController.xib file which is mapped to your controller class “HelloWorldViewController.h. For now I just want to change in HelloWorldViewController.xib file. Double click on that file to open it inside interface builder.

customize UITableView using UITableViewCell
Structure of your iPhone application
customize UITableView using UITableViewCell
Interface builder Look

Step 7:Click on Tools and select Libaray (cmd + shift + L) and drag the text field to your view. As text field is already selected, click on Tools>Inspector (cmd + 1) and in Text field type “Your Name”.

customize UITableView using UITableViewCell
Add label to your First iPhone application
customize UITableView using UITableViewCell
Change text in your UILable

Step 8:Now drag the TextField from Library to your view (cmd+shift+L) and also drag another Label inside view. Make sure label is selected, Click on tools and select “Size Inspector” (cmd + 3) and change the width of this text field to 250. Also go to tools and select Inspector, change the layout to center.

customize UITableView using UITableViewCell
Add Text field to your first iPhone application
customize UITableView using UITableViewCell
Add another label to your First iPhone application
customize UITableView using UITableViewCell
Change Label Width
customize UITableView using UITableViewCell
Center UILabel from Interface Builder

Step 9:Last thing is to drag a button to the view (19) and then open Inspector again by selecting tools>Inspector. In Title type “Submit”.

customize UITableView using UITableViewCell
Add button to your First iPhone Application
customize UITableView using UITableViewCell
Change Text in your UIButton

Step 10:Now map the controller class variable function and methods with interface builder. Select File’s Owner in Interface builder and select connection inspector from Tools cmd + 2

customize UITableView using UITableViewCell
Map your controller with Interface Builder

Step 11:Now you can see that two new variables are added in connection inspector txtUserName and lblUserTypedName. Click on txtUserName radio button and drag it to text field in view (as you can see in the image)

customize UITableView using UITableViewCell
Map your text field with Interface builder

Step 12:Do the same with lblUserTypedName, select its radio and drag it to below label.

customize UITableView using UITableViewCell
Map your label field with Interface builder

Step 13:Now the last step is, click on submitYourName radio and drag it to the button and select touch down from the list.

customize UITableView using UITableViewCell
Map your button with Interface builder
customize UITableView using UITableViewCell
Set action type of Button

Step 14:Now close the interface and open xcode. Either press cmd + r or cmd + enter or simply press of “build and go” button to run this hello world application. It will open the simulator in iPhone.
Final output

customize UITableView using UITableViewCell
Your first iPhone application Running in simulator

iPhone hello world tutorial code

You can grab this code from here.

Now watch me doing it

Click on this link to view the video screen cast for hello world iPhone application tutorial

1 Introduction


구글은 안드로이드가 운영체제, 미들웨어 그리고 중요 프로그램을 포함하는 임베디드 디바이스를 위한 소프트웨어 스택이라고 설명합니다. 이 문서는 구글 안드로이드 아키텍처에 대해 설명하고 실제 하드웨어에 포팅하는 절차를 설명합니다. 설명은 안드로이드 에뮬레이터의 m3 SDK 버전에 기초해서 설명합니다.

여러분이 커널 패치, 패치의 거부 해결, 램디스크 이미지 만들기, 리눅스 커널 자체에 대한 충분한 지식을 가지고 있다면 이 아티클은 쉬울 것입니다.

2 Copyright and Acknowledgements


이 문서의 소유권은 Kwangwoo Lee <Kwangwoo.lee@gmailREMOVETHIS.com> 에게 있습니다. 이 문서에 대한 복사, 배포, 수정에 대한 권리는 GNU Free Documentation License 를 따릅니다.

번역은 양정석(dasomoli@gmailREMOVETHIS.com) 이 하였습니다만, 이상한 곳이 있다면 가차없이 수정해 주세요. :) 원문 : http://wiki.kldp.org/wiki.php/AndroidPortingOnRealTarget

3 안드로이드 아키텍처의 요약 분석


3.1 안드로이드 커널


안드로이드 커널의 가장 큰 차이점은 ARM EABI(Embedded Application Binary Interface)와 OpenBinder IPC(Inter Process Communication)를 사용한다는 것입니다. 여러분이 ARM EABI를 지원하는 커널을 컴파일하려면, ARM EABI를 지원하기 위한 툴체인(toolchains)을 새로 빌드하여야 합니다.

안드로이드 SDK는 Qemu를 사용하여 goldfish 아키텍처를 에뮬레이션합니다. alsa는 안드로이드의 오디오를 위해서 사용됩니다. goldfish 아키텍처 디렉토리의 audio.c 파일을 보고, 드라이버는 안드로이드 시스템 상의 오디오를 위한 /dev/eac를 사용합니다. 또한 RTC(Real Time Clock) 장치는 /dev/rtc0를 통해 사용됩니다.

다음 파트들은 주된 차이점을 설명합니다:

3.1.1 ARM EABI


EABI는 ARM사(ARM Ltd.)에 의한 새로운 "임베디드" ABI입니다. 그 차이는 데비안 위키에 정리되어 있습니다.

  • FPU를 쓰거나 쓰지 않는, 빠른 실수 연산(floating point) 성능
  • soft 와 hardfloat 코드의 혼용 가능
  • 이전에 사용되어지던 것과 같이 구조체 팩킹(packing)이 고통스럽지 않습니다.
  • 다른 툴들과의 더 나은 호환성(compatibility)
  • 더 효율적인 syscall 관례(convention). (http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3105/4)

long ftruncate64(unsigned int fd, loff_t length); 의 예:기존 ABI:- put fd into r0 (fd를 r0로 넣음)- put length into r1-r2 (길이를 r1-r2로 넣음)- 커널 호출을 위해서 "swi #(0x900000 + 194)" 사용.새로운 ARM EABI:- put fd into r0 (fd를 r0로 넣음)- put length into r2-r3 (skipping over r1) (길이를 r2-r3로 넣음. r1은 무시)- put 194 into r7 (194를 r7로 넣음)- use "swi 0" to call the kernel (커널을 호출하기 위해서 "swi 0" 사용)

안드로이드는 EABI 커널 기능을 사용합니다. CONFIG_AEABI 와 CONFIG_OABI_COMPAT의 커널 옵션을 활성화 하세요. 여러분은 다음과 같은 실행 바이너리의 차이를 볼 수 있습니다:

  • 기존 ABI
$ arm-softfloat-linux-gnu-objdump -x t7-demo | grep privateprivate flags = 202: [APCS-32] [FPA float format] [software FP] [has entry point]$ file t7-demot7-demo: ELF 32-bit LSB executable, ARM, version 1 (ARM), for GNU/Linux 2.4.3, dynamically linked (uses shared libs), for GNU/Linux 2.4.3, stripped

  • ARM EABI
$ arm-softfloat-linux-gnueabi-objdump -x t7-demo  | grep privateprivate flags = 4000002: [Version4 EABI] [has entry point]$ file t7-demot7-demo: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.14, dynamically linked (uses shared libs), for GNU/Linux 2.6.14, stripped


ARM 아키텍처를 위한 ABI가 무엇인가요? ARM EABI와 같은 건가요?

ARM 아키텍처의 ABI는 ARM와 (CodeSourcery를 포함하는) 그 파트너들에 의해 개발된 어떻게 컴파일러와 어셈블러와 링커와 다른 비슷한 툴들이 Object 파일과 실행 파일을 생성해야만 하는지를 설명하는 표준입니다. ARM 아키텍처의 ABI를 정확히 구현한 툴들은 상호 운용(interoperate)될 수 있습니다:예를 들면, 다른 툴체인에서 빌드된 Object 파일과 또 다른 툴체인에서 빌드된 Object파일이 양 쪽의 컴파일러가 ARM 아키텍처의 ABI를 사용한다면 함께 합쳐질 수 있습니다. "ARM EABI"는 ARM 아키텍처 ABI의 또다른 이름입니다.

3.1.2 OpenBinder


OpenBinder는 객체지향(object-oriented) 운영체제 환경을 제공합니다. 전통적인 커널에 호스팅(to be hosted)되어지도록 설계되었습니다. 이 프로젝트는 BeOS 다음번 생성의 일부로 Be. Inc에서 시작되었고, Cobalt 시스템의 코어 부분으로 PalmSource에 구현이 완료되었습니다. 그 것은 시스템이 Application에 지향보다는 컴포넌트 아키텍처에 지향적이고, 프로세스 간의 IPC, 스레드풀, 메모리 관리와 클린 업(clean up) 기능을 바인더 Obejct의 참조의 끝에서 제공합니다. 바닐라(vanilla) 커널은 OpenBinder IPC 메카니즘을 가지고 있지 않으므로, 여러분은 커널에 패치하여야 합니다. OpenBinder는 시스템의 스레드 관리를 /dev/binder를 통해서 제공합니다. 그 것이 안드로이드가 스레드 라이브러리를 제공하지 않는 이유입니다.

커널 패치 후에, 여러분은 /drivers/binder/에서 바인더를 위한 파일을 볼 수 있을 것입니다.

3.1.3 프레임 버퍼


기본적인 프레임 버퍼 드라이버는 이미 구현되어져 있어야만 합니다. 그 후에 여러분은 여러분의 아키텍처 드라이버와 goldfish 드라이버 간의 차이를 구현해야 할 것입니다.

goldfish 아키텍처의 프레임 버퍼 드라이버는 struct fp_ops의 fb_pan_display 함수를 지원합니다. 그 것은 실제 프레임 크기보다 두 배의 메모리가 할당되어야 함을 의미합니다.

  • 프레임 버퍼 정보 초기화
struct fb_info *fbinfo;...fbinfo->fix.ypanstep	= 1;fbinfo->var.yres_virtual    = gm->lcd.yres * 2;fbinfo->fix.smem_len        =	(gm->lcd.xres *                                gm->lcd.yres *                                gm->lcd.bpp / 8) * 2;

  • 프레임 버퍼 메모리 할당
struct mvfb_info *fbi;...fbi->map_size = PAGE_ALIGN(fbi->fb->fix.smem_len + PAGE_SIZE);fbi->map_cpu  = dma_alloc_writecombine(fbi->dev, fbi->map_size,                                       &fbi->map_dma, GFP_KERNEL);

  • fb_pan_display 함수 후킹 구현
static int mvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fb){...}static struct fb_ops mvfb_ops = {        .owner		= THIS_MODULE,        .fb_check_var	= mvfb_check_var,        .fb_set_par	= mvfb_set_par,	        .fb_setcolreg	= mvfb_setcolreg,        .fb_blank	= mvfb_blank,        .fb_pan_display = mvfb_pan_display,        .fb_fillrect	= cfb_fillrect,        .fb_copyarea	= cfb_copyarea,        .fb_imageblit	= cfb_imageblit,        .fb_mmap	= mvfb_mmap,	};

그 디바이스 파일은 /dev/graphics/fb0에 위치해 있습니다.

3.1.4 입력 장치


안드로이드는 사용자 입력을 위한 이벤트 디바이스를 사용합니다. 거기에는 키패드와 쿼티2(qwerty2) 키보드와 마우스와 같은 세가지 디바이스가 있습니다. 쿼티2(qwerty2) 키보드와 마우스는 보통 디바이스입니다. 그래서 마우스 디바이스를 대체하는 키패드와 터치스크린을 설명하겠습니다.

안드로이드 쉘에서 /proc/bus/input/{devices,handlers}를 cat 하면, 안드로이드에서 사용되는 디바이스들을 볼 수 있습니다.
$ adb shell# cat /proc/bus/input/devicesI: Bus=0000 Vendor=0000 Product=0000 Version=0000N: Name="goldfish-events-keyboard"P: Phys=S: Sysfs=/class/inut/input0U: Uniq=H: Handlers=kbd mouse0 event0...## cat /proc/bus/input/handlersN: Number=0 Name=kbdN: Number=1 Name=mousedev Minor=32N: Number=2 Name=evdev Minor=64#

  • 키패드
Qemu는 goldfish-events-keyboard를 에뮬레이트합니다. 그 것은 이벤트 디바이스(/dev/input/event0)를 사용하는 키패드입니다. 그래서 여러분은 이벤트 디바이스로부터 실제 활성화된 안드로이드 프로그램으로 전달되어지는 키 이벤트의 종류와 값을 알 수 있습니다. 그렇게 하기 위해서 event0 디바이스를 cat으로 읽고 파일로 그 출력을 재지정(redirect)합니다. 만약 에뮬레이터 상의 키 버튼이 눌리고 떼어지면 그 출력 값이 저장될 것입니다.

그 출력 형식은 input_event 구조체 입니다. 그래서 각 event의 출력은 시간을 위한 8 바이트, 타입을 위한 2 바이트, 코드를 위한 2 바이트, 값을 위한 4바이트로 총 16 바이트입니다. 리눅스 커널 소스 코드의 Documentation/input 디렉토리의 입력 이벤트 디바이스(input event device)에 관한 input.txt를 읽고, input-programming.txt를 읽으세요.
struct input_event {        struct timeval time;        unsigned short type;        unsigned short code;        unsigned int value;};

Tiger7 개발 보드는 그 고유의 scancode 테이블을 가집니다. 다음은 개발보드의 키 레이아웃과 scancode 테이블과 안드로이드 키 코드를 보입니다:
/* *  Key Layout       Scancode Table * *   1  2  3        0x1  0x10  0x100 *   4  5  6        0x2  0x20  0x200 *   7  8  9        0x4  0x40  0x400 *   *  0  #        0x8  0x80  0x800 */static unsigned short android_keycode[] = {        /*         *  0x66 0x67 0x9e	Home  Up   Back         *  0x69 0xe8 0x6a	Left  Ok   Right         *  0xe7 0x6c 0x6b	Send  Down Hangup         *  0xe5		Menu       just_distinction_for_private         */        KEY_HOME,         KEY_UP,       KEY_BACK,        KEY_LEFT,         KEY_REPLY,    KEY_RIGHT,        KEY_SEND,         KEY_DOWN,     KEY_END,        KEY_KBDILLUMDOWN, KEY_RESERVED, KEY_PLAY};

에뮬레이터에는 전원(power) 버튼이 있습니다. 그러나 출력 값을 얻기 위해서 무시했습니다.

키패드의 인터럽트가 감지(caught)되면 위 테이블의 안드로이드의 키 코드로 scancode를 변환하고 사용자 공간(user space) 프로그램으로 이벤트를 보냅니다.
...keycode = translate_keycode(scancode);...input_event(keydev->input, EV_KEY, keycode, KEY_PRESSED);orinput_event(keydev->input, EV_KEY, keycode, KEY_RELEASED);...

고정밀도 타이머 - hrtimer는 키패드 debounce를 줄이기 위해서 사용되었습니다.

  • 터치 스크린

포인팅 디바이스를 위한 이벤트 인터페이스를 지원하는 터치스크린 드라이버를 갖고 있다면, 잘 동작할 것입니다. 그렇지 않다면, 다른 포인팅 디바이스를 사용하거나 구현해야 합니다. 다행스럽게도 개발보드는 이미 안드로이드 포팅을 시작하기 전에 만들어진 터치스크린 드라이버 - drivers/input/touchscreen/tsc2007.c -가 구현되어 있었습니다. 여러분 고유의 드라이버를 구현하기 위해서는 drivers/input/touchscreen/ 의 드라이버와 Documentation/input/의 텍스트 파일을 참고하세요.
여기 개발 보드 상의 /proc/bus/input/{devices,handlers}의 출력이 있습니다.
# cat /proc/bus/input/devicesI: Bus=0000 Vendor=0000 Product=0000 Version=0000N: Name="MVT7 KEYPAD"P: Phys=S: Sysfs=/class/input/input0U: Uniq=H: Handlers=kbd event0 evbugB: EV=f...I: Bus=0000 Vendor=0000 Product=0000 Version=0000N: Name="TSC2007 Touchscreen"P: Phys=0-0090/input0S: Sysfs=/class/input/input1U: Uniq=H: Handlers=event1 evbugB: EV=bB: KEY=400 0 0 0 0 0 0 0 0 0 0B: ABS=1000003# cat /proc/bus/input/handlersN: Number=0 Name=kbdN: Number=1 Name=evdev Minor=64N: Number=2 Name=evbug

결과에서 보는 것과 같이, 프로그램 계층(application layer)에서 키패드는 /dev/input/event0를 사용하고, 터치스크린 인터페이스는 /dev/input/event1를 사용합니다.

3.1.5 Low Memory Killer


리눅스 커널은 프로세스의 요청을 위한 할당을 위해서 남은 메모리가 없는 상황을 위한 OOM(Out of Memory) 킬러를 가지고 있습니다. 그 것은 모든 프로세스를 시험하고 어떤 제약으로 점수를 매깁니다. 최고 점수의 init을 제외한 프로세스는 죽여집니다.

안드로이드의 Low Memory Killer는 OOM 킬러와 약간 다릅니다. 그 것은 그룹의 중요성에 따라 프로세스를 분류하고 가장 낮은 그룹의 프로세스를 죽입니다. 그 것은 시스템을 최종 사용자(end user) 관점에서 안정적이게 만듭니다. 예를 들면, UI 프로세스 - foreground process -는 최종 사용자에게 가장 중요한 프로세스입니다. 그래서 프로세스를 지키는 것은 다른 background 프로세스의 삶을 지키는 것보다 더 안정적으로 보이는 것을 살립니다.

커널 패치 후에 CONFIG_LOW_MEMORY_KILLER 를 활성화하세요.

3.1.6 안드로이드 로거(Android Logger)


여러분이 이 기능을 활성화하면 /dev/log/main를 통해 안드로이드에 관한 유용한 정보를 볼 수 있습니다. main, events, radio 같은 /dev/log 상의 세가지 디바이스 파일이 있습니다. /dev/log/radio 파일은 안드로이드 시스템 상의 모뎀과 ril 데몬 - rild - 에 관련된 것을 보여줍니다.

이 로거를 활성화할때, 시스템 성능은 시스템 상에서 약간 느려집니다. 이 기능을 사용하기 위해서 CONFIG_ANDROID_LOGGER를 활성화하세요.

3.1.7 안드로이드 파워(Android power)


안드로이드 파워는 디바이스 상의 배터리 관리과 전원 관리에 관련된 파일 시스템 상의 inotify 기능과 같은 서브시스템을 위한 것입니다. 그 것은 안드로이드 시스템의 init 바이너리를 통해 안드로이드를 시작하기 위해서 필요합니다. 그러나 runtime 바이너리는 안드로이드의 수동 시작 상에서 안드로이드 파워에 따르는 어떤 파일 - /sys/android_power/acruire_partial_wake_lock - 을 찾고 시작에 실패합니다. 사용하기 위해서는 CONFIG_ANDROID_POWER 옵션을 활성화시키세요.

3.1.8 Panic Timeout


개발 보드 상의 안드로이드 시작을 위해서 필요없습니다. CONFIG_PANIC_TIMEOUT 를 원하는 값으로 설정하세요.

3.2 안드로이드 루트 파일 시스템


안드로이드 에뮬레이터는 tools/lib/images디렉토리 상에 3개의 기본 이미지를 가집니다.

  • ramdisk.img
  • system.img
  • userdata.img

ramdisk.img 은 gzip으로 압축된 cpio 파일입니다. 램디스크 이미지는 매우 작고, 설정 파일과 init과 recovery 같은 실행파일을 포함합니다. init 파일은 정식 System V init은 아닙니다. 그 것은 안드로이드를 위해 만들어졌고, 안드로이드 시스템을 시작하기 위한 특별한 것을 수행합니다.

system.img 와 userdata.img 는 VMS Alpha 실행파일입니다. system.img와 userdata.img 는 루트 파일 시스템 상의 /system 과 /data 디렉토리의 내용을 가집니다. 그들은 NAND 디바이스 상에 yaffs2 파일 시스템으로 맵핑되어 있습니다. /dev/block/mtdblock0 는 /system 이고, /dev/block/mtdblock1 은 /data 입니다.

/system 디렉토리는 라이브러리와 기본 시스템 패키지(*.apk)를 가지고 있습니다. /data 디렉토리는 타임존, 캐쉬, ApiDemos.apk 패키지를 가지고 있습니다.

주 서비스는 zygote(/system/bin/app_process), runtime(/system/bin/runtime), 그리고 dbus(/system/bin/dbus-daemon) 입니다. 여러분은 안드로이드 램디스크 상의 /etc/init.rc 파일을 볼 수 있습니다.

...zygote {    exec /system/bin/app_process    args {        0 -Xzygote        1 /system/bin        2 --zygote    }    autostart 1}runtime {    exec /system/bin/runtime    autostart 1}...dbus {    exec /system/bin/dbus-daemon    args.0 --system    args.1 --nofork    autostart 1}...

3.3 안드로이드 패키지의 라이센스


tools/lib/images/NOTICE 는 패키지 리스트와 각 라이브러리의 라이센스를 포함하고 있습니다. 라이센스 표는 2008 Korea Android Summit에서 임근식 씨의 발표로부터 게시되었습니다.

Open Source License
Linux Kernel GPL
NetBSD C Library BSD
DBUS GPL2
OpenBinder (core) GPL2
YAFFS2 GPL
SQLite GPL2
Webkit BSD (including LGPL)
WebCore LGPL
SDL LGPL
SGL Google(Skia)
OpenGL SGI OpenGL (BSD/MPL)


4 ARM EABI를 지원하는 툴체인


툴체인은 시스템 개발에 사용되어지는 툴들을 말합니다. C/C++ 컴파일러, 링커, 라이브러리, binutils와 기타 다른 것들을 포함합니다. 안드로이드 커널과 시스템은 EABI 지원을 필요로 합니다. 그래서 기존 툴체인은 안드로이드 시스템을 만드는데 호환되지 않습니다.

4.1 툴체인 빌드하기


더 쉽게 삶을 살기 위해서, Dan Kegel에 의한 crosstool-0.43 스크립트(http://www.kegel.com/crosstool/ )를 사용했습니다. 불행히도 그 것은 eabi 툴체인을 빌드하기 위한 지원을 하지 않습니다. 그래서 Khem Raj의 a glibc 2.5+ nptl build for arm softfloat eabi patch (http://sources.redhat.com/ml/crossgcc/2006-12/msg00076.html )를 적용했습니다.
$./arm-softfloat-eabi.sh

네트워크가 연결되어 있다면, 스크립트가 gcc 4.1.1 과 glibc 2.5을 사용해서 툴체인을 다운로드하고 빌드해 줄 겁니다.

4.2 다른 툴체인


Codesourcery 툴체인을 사용하지 않았습니다만, 그들은 그 것이 안드로이드 시스템 빌드를 위해서 잘 동작할 것이라고 말하고 있습니다.


5 커널


실제 하드웨어 상에 안드로이드를 포팅하는 것은 Benno (http://benno.id.au )에 의해서 시작되었습니다. 여러분은 그의 블로그에서 유용한 정보를 볼 수 있습니다. 그의 블로그는 pre-compiled static binaries를 링크합니다. 그것은 안드로이드 시스템 디버깅에 매우 유용합니다. 여러분 역시, static build busybox와 strace 바이너리를 빌드할 수 있지만, 갖다 쓰는 게 더 좋을 겁니다.

여러분은 안드로이드 커널과 바닐라 커널 2.6.23 버전 사이의 차이를 포함한 패치 파일을 얻을 수 있습니다. 그 것은 그것들 사이의 모든 차이를 가집니다. 그래서 여러분은 그것들의 일부를 추출할 필요가 있고, 여러분의 시스템 아키텍처를 위한 여러분 고유의 패치를 만들 수 있습니다.

예를 들면, 안드로이드 커널은 그 고유의 yaffs 파일 시스템 패치를 가집니다. 여러분의 아키텍처상에서 여러분 고유의 yaffs 나 jffs2 같은 어떤 다른 파일 시스템을 가진다면, yaffs 패치의 일부를 제거해야 합니다. 안드로이드 커널이 에뮬레이트하는 qemu 상의 ARM 아키텍처의 goldfish 아키텍처는 여러분의 아키텍처의 일부가 될 필요가 없습니다. 제거 될 수 있습니다.

안드로이드 커널은 ARMv5 명령을 에뮬레이트합니다. 그래서 ARM926EJ-S (ARMv5TEJ)는 작업하기 매우 좋을 겁니다.

5.1 커널 패치


Benno 는 openmoko의 NEO1973 디바이스로 작업했습니다. 그래서 그는 그 것을 위한 패치 파일을 만들었습니다. http://benno.id.au/blog/2007/11/21/android-neo1973 에서 원본 패치 파일을 얻고, android.diff를 사용했습니다. 그 것은 goldfish, qemu, yaffs 그리고 안드로이드에 특정적인 부분에 관한 전부를 가지고 있습니다.

여러분은 직접 패치 파일을 편집하고 제거할 수 있습니다. goldfish와 qemu에 특정적인 부분을 제외한 binder, 안드로이드 파워, 안드로이드 로거, low memory 킬러를 포함하는 패치를 만든 후에 바닐라 리눅스 커널 2.6.23을 얻고, 그 걸로 패치하세요.

여러분이 2.6.24.1 버전 리눅스 커널을 사용한다면 안드로이드 파워에 관련된 부분이 동작을 위해서 비활성화 되거나 적절히 고쳐져야 합니다.

5.2 .config


  • 필수적인 부분
...CONFIG_PANIC_TIMEOUT=0CONFIG_AEABI=yCONFIG_OABI_COMPAT=yCONFIG_BINDER=yCONFIG_LOW_MEMORY_KILLER=y...

  • 필요에 따른 부분
...# CONFIG_ANDROID_GADGET is not set# CONFIG_ANDROID_RAM_CONSOLE is not set# CONFIG_ANDROID_POWER is not set# CONFIG_ANDROID_LOGGER is not set...

6 루트 파일 시스템


루트 파일 시스템은 램 상의 기본 램디스크 이미지, NAND dev0 (/dev/block/mtdblock0) 그리고, NAND dev1 (/dev/block/mtdblock1)의 자료 이미지, 세가지 부분으로 제작되어 있습니다. MTD 디바이스는 yaffs2 파일 시스템을 가지고 각각은 안드로이드 에뮬레이터 상에서 64MiB 용량을 가집니다.

추출된 system 과 data 디렉토리는 실제 존재하는 NAND 디바이스 상에 복사되었고, 그들은 실제 하드웨어에서 동작시키기 위해서 --bind 옵션으로 마운트되어졌습니다.

6.1 에뮬레이터에서 램디스크 이미지 얻기


1. tools/lib/images/ramdisk.img에서 ramdisk 이미지를 unpack
$ gzip -cd ramdisk.img > ramdisk$ cpio -iv -F ramdisk

cpio 는 현재 작업중인 디렉토리상에 파일과 디렉토리를 푼다.

2. 램디스크의 내용 목록

datadevetcetc/default.propetc/firmwareetc/firmware/brf6150.binetc/firmware/brf6300.binetc/hcid.confetc/hostsetc/init.gprs-pppdetc/init.rcetc/init.riletc/init.testmenuetc/pppetc/ppp/chap-secretsetc/ppp/ip-downetc/ppp/ip-upetc/qemu-init.shetc/system.confetc/system.detc/system.d/bluez-hcid.confetc/usbd.confinitprocsbinsbin/recoverysyssystemtmpvarvar/run

6.2 에뮬레이터에서 data와 system 디렉토리 얻기



data와 system 디렉토리를 얻기 위해서 여러분은 busybox 바이너리를 static 컴파일하여야 합니다. 컴파일된 바이너리는 http://benno.id.au/blog/2007/11/14/android-busybox 에서 얻거나, 여러분 고유의 바이너리를 만들 수 있습니다.

1. 안드로이드 에뮬레이터를 실행시키세요.

2. 에뮬레이터 안에 static 컴파일된 busybox를 넣으세요.
# adb push busybox .

3. 안드로이드 쉘을 실행시키세요.
# adb shell

4. busybox로 tarball을 만드세요.
# chmod +x /busybox# busybox tar -c /data.tar /data# busybox tar -c /system.tar /system# exit

5. 에뮬레이터에서 tarball을 추출하세요.
# adb pull /data.tar .# adb pull /system.tar .

추출 명령은 종종 실패합니다. 성공적으로 될 때까지 계속 실행하세요.

6.3 존재하는 램디스크 이미지로 안드로이드 시스템을 통합하기


여러분의 아키텍처의 램디스크는 여러분의 작업을 조금 더 쉽게 만듭니다. system과 data 디렉토리를 제외한 안드로이드 램디스크의 내용을 여러분 고유의 램디스크로 복사하세요. 그리고 그냥 system과 data 디렉토리의 마운트 지점을 만드세요. 마운트 지점은 나중에 bind 옵션으로 사용될 수 있습니다. 안드로이드 램디스크 이미지의 init 바이너리는 시스템을 시작하기 위한 중요 바이너리이고, 그것은 /etc/init.rc 파일 상에서 설정 파일을 읽습니다.

/etc/init.rc를 편집하고 qemu 부분을 주석으로 만드세요.
...startup {        ...#       qemu-init {#           exec /etc/qemu-init.sh#       }}...

run.sh 스크립트를 만드세요. /dev/block/mtdblock5는 실제 NAND 디바이스의 mtd 파티션이고, 그 것은 /mnt 상에 마운트되어 집니다. data와 system 디렉토리는 이미 mtdblock5 상에 복사되어져 있습니다. 그래서 그 스크립트는 아래와 같이 / 상의 각 디렉토리의 바인드 마운팅(bind mounting)을 보입니다. 여러분의 보드 설정에 따라 스크립트를 고치세요.
#!/bin/shmount -t yaffs /dev/block/mtdblock5 /mntmount --bind /mnt/data   /datamount --bind /mnt/system /system# data folder is owned by system user on emulator. Fix 777 to other.chmod 777 /data#chmod 777 /systemexport PATH=/system/sbin:/system/bin:/sbin/usr/local/binexport LD_LIBRARY_PATH=/system/libexport ANDROID_BOOTLOGO=1export ANDROID_ROOT=/systemexport ANDROID_ASSETS=/system/appexport EXTERNAL_STORAGE=/sdcardexport ANDROID_DATA=/dataexport DRM_CONTENT=/data/drm/content/init &

터치스크린을 위한 필요에 따른 설정 - TSLib.
...export TSLIB_CONSOLEDEVICE=noneexport TSLIB_FBDEVICE=/dev/fb0export TSLIB_TSDEVICE=/dev/input/event1export TSLIB_CALIBFILE=/etc/pointercalexport TSLIB_CONFFILE=/etc/ts.confexport TSLIB_PLUGINDIR=/lib/tsexport LD_PRELOAD=/lib/libts.so:/lib/ts/pthres.so...

6.4 System 과 data 디렉토리


system 과 data 디렉토리의 내용은 이미 mtdblock5에 이미 복사되어져 있습니다. 여러분은 여러분 고유의 방법으로 복사하셔야 합니다. 그것을 사용하기 위해서 저는 루트 디렉토리상에 바인드 마운팅(bind mounting)을 선택했습니다. 바인드 마운팅은 이미 존재하는 디렉토리를 새로운 마운트 포인트로 마운트하는 기술입니다.

6.5 실행과 디버그


이제 커널과 램디스크와 자료 디렉토리 - data와 system -이 준비되었습니다. 빨간 사일런 눈을 볼 시간입니다. 여러분의 통합된 시스템을 부팅하고 나서 run.sh를 루트 디렉토리에서 실행하세요.
# cd /# . /android/run.shyaffs: dev is 32505861 name is "mtdblock5"yaffs: passed flags ""yaffs: Attempting MTD mount on 31.5, "mtdblock5"yaffs: auto selecting yaffs2# init: HOW ARE YOU GENTLEMENinit: reading config fileinit: device initinit: mtd partition -1,init: mtd partition 0, "l1boot"init: mtd partition 1, "u-boot"init: mtd partition 2, "params"init: mtd partition 3, "kernel"init: mtd partition 4, "ramdisk"init: mtd partition 5, "rootfs"sh: can't access tty; job control turned off# binder_open(c394bcc8 c3c731a0) (pid 1577) got c3e48000binder_open(c394bcc8 c3cd8dc0) (pid 1616) got c319f000binder_open(c394bcc8 c3cd8ac0) (pid 1673) got c3d10000binder_open(c394bcc8 c3cd8940) (pid 1680) got c0e19000binder_open(c394bcc8 c3cd88c0) (pid 1691) got c2fa0000binder_open(c394bcc8 c3d174a0) (pid 1592) got c25b8000binder_release(c394bcc8 c3cd88c0) (pid 1691) pd c2fa0000#

  • /dev 상에 eac 디바이스 파일을 만들지 마세요. 그 것은 qemu상의 오디오를 위한 것입니다. 만약 있다면 시작 절차(start up sequence)는 사운드 디바이스에 어떤 데이터를 쓰는 것을 끝마치기 위해서 영원히 기다릴 것입니다.
  • 수동 시작(manual startup) 대신에 안드로이드 init 바이너리를 사용하세요. 수동 시작은 안드로이드 패치가 필요합니다. 그 경우 시작 절차는 /sys/android_power/acquire_partial_wake_lock에 접근하고 기다릴 것입니다.

안드로이드 시스템을 디버깅하기 위해서 http://benno.id.au/blog/2007/11/18/android-runtime-strace 의 static 컴파일된 strace 바이너리를 사용하고, 안드로이드를 수동으로 실행하세요.

#!/bin/sh# set environment variables above example.../system/bin/app_process -Xzygote /system/bin --zygote &/system/bin/dbus-daemon --system &/system/bin/runtime

다음 예제는 수동 시작 절차를 보여줍니다. /system/bin/runtime 바이너리 상에서 strace를 사용하세요.

./strace -ff -F -tt -s 200 -o /tmp/strace runtime

6.6 스크린샷


recvfrom(4, "add@/devices/virtual/misc/networ"..., 1024, 0, NULL, NULL) = 144mknod("/dev/network_latency", S_IFCHR|0600, makedev(10, 58)) = 0chown32("/dev/network_latency", 0, 0)   = 0recvfrom(4, 0xbee2b72a, 1024, 0, 0, 0)  = -1 EAGAIN (invain)getdents64(8, /* 5 entries */, 4200)    = 136getdents64(8, /* 0 entries */, 4200)    = 0close(8)                                = 0SYS_305(0x7, 0x27f3b, 0x24000, 0, 0x28e98) = 8SYS_305(0x8, 0x1b6ec, 0x20001, 0, 0x28e98) = 9write(9, "add\n", 4)                    = 4close(9)                                = 0recvfrom(4, "add@/devices/virtual/misc/networ"..., 1024, 0, NULL, NULL) = 150mknod("/dev/network_throughput", S_IFCHR|0600, makedev(10, 57)) = 0chown32("/dev/network_throughput", 0, 0) = 0recvfrom(4, 0xbee2b72a, 1024, 0, 0, 0)  = -1 EAGAIN (Resource temporarily unavailable)getdents64(8, /* 5 entries */, 4200)    = 136getdents64(8, /* 0 entries */, 4200)    = 0close(8)                                = 0getdents64(7, /* 0 entries */, 4200)    = 0close(7)                                = 0SYS_305(0x6, 0x26f13, 0x24000, 0, 0x27e18) = 7SYS_305(0x7, 0x1b6ec, 0x20001, 0, 0x27e18) = -1 ENOENT (No such file or directory)getdents64(7, /* 3 entries */, 4200)    = 80SYS_305(0x7, 0x27e6b, 0x24000, 0, 0xffffffff) = 8SYS_305(0x8, 0x1b6ec, 0x20001, 0, 0x28e98) = 9write(9, "add\n", 4)                    = 4close(9)                                = 0recvfrom(4, "add@/devices/virtual/sound/timer"..., 1024, 0, NULL, NULL) = 128mknod("/dev/timer", S_IFCHR|0600, makedev(116, 33)) = 0chown32("/dev/timer", 0, 0)             = 0recvfrom(4, 0xbee2b72a, 1024, 0, 0, 0)  = -1 EAGAIN (Resource temporarily unavailable)getdents64(8, /* 5 entries */, 4200)    = 136getdents64(8, /* 0 entries */, 4200)    = 0close(8)                                = 0getdents64(7, /* 0 entries */, 4200)    = 0close(7)                                = 0getdents64(6, /* 0 entries */, 4200)    = 0close(6)                                = 0getdents64(5, /* 0 entries */, 4200)    = 0close(5)                                = 0

7 애플리케이션 개발


안드로이드 애플리케이션은 XML 레이아웃과 자바 문법을 사용합니다만, 자바는 아닙니다. 왜냐하면 그들은 그들 고유의 가상 머신 - dalvik - 과 dex 파일 형식을 위한 컴파일러를 사용하기 때문입니다. 그리고 Home.apk, Phone.apk, ApiDemos.apk 등 과 같이 apk로 이름붙여진 패키지를 사용합니다.

apk 파일은 ZIP 압축파일이고 네 가지 부분을 가집니다.

  • AndroidManifest.xml
  • classes.dex
  • resources.arsc
  • res 디렉토리

Dex 파일 형식은 http://www.retrodev.com/android/dexformat.html 에 설명되어져 있습니다. 그리고 그 파일들의 내용과 디렉토리는 언젠가 구글이 설명할 겁니다. 현재는 설명되지 않았습니다. 우리는 단지 그렇게 추측할 뿐입니다.

안드로이드 SDK는 *.apk 파일을 생성할 것입니다.

7.1 이클립스(Eclipse) 통합개발환경(IDE) 설치하기


http://code.google.com/android/intro/installing.html 의 설치 절차를 따르세요.

1. http://www.eclipse.org/downloads/ 의 (JDT와 WST 플러그인이 포함된)Eclipse IDE for Java developer


3. Apache Ant를 포함하는 eclipse plugin인 ADT (Android Development Tools)

7.2 샘플 애플리케이션을 빌드하고 실행하기


1. 샘플 프로젝트를 열고 빌드

2. 에뮬레이터 상에서 샘플 애플리케이션 실행

7.3 스크린샷


  • 노키아의 N810 제품(arm1136jf-s) 상의 안드로이드 플랫폼
    http://wiki.kldp.org/pds/AndroidPortingOnRealTarget/n810.kandroid200805.PNG

  • Android Platform on arm1136jf-S for another CE Product.
    fi.armadillo500.android1.0.jpg


8 에필로그


안드로이드 시스템은 데비안, 레드햇, 수세나 기타 등과 같은 모바일 환경을 위한 새로운 종류의 리눅스 기반의 배포판이 될 것으로 보입니다. 그들은 오픈소스 세상의 리눅스 커널과 많은 다른 라이브러리를 사용할 뿐입니다. 그들은 현재 3D 가속화를 OpenGL-ES 라이브러리에 기반한 소프트웨어를 제공합니다. 그러나 그들은 그를 위한 하드웨어 가속의 기본 프로세서 상에서 개발하고 있습니다. 그 하드웨어 가속은 추후의 빠른 UI 렌더링 효과를 위해 필수적입니다.

SDK 상의 안드로이드 시스템은 실제 하드웨어 상에 포팅하는 것은 완벽하지 않습니다. 왜냐하면, 라이브러리와 클래스에 관련된 어떤 디바이스 - 예를 들면, 카메라 -는 아직 구현되지 않았고, 사용자에게 공개되지 않았습니다. 그 것은 아직 개발 단계에 있는 것으로 보입니다. 그래서 구글의 전체 포팅 킷을 기다리는 것이 더 나을 것 같습니다.

그 전에, 우리는 안드로이드 시스템의 사업 모델을 살펴봐야만 합니다. 그 것은 약간 빠른 CPU 성능을 필요로 하기 때문에 운송 판매사는 싼 기본 프로세서(RF 부분)와 멀티미디어 코프로세서(co-processor)가 필요할 겁니다. 멀티미디어 기능을 포함하는 기본 프로세서는 매우 비싸기 때문입니다.

9 링크와 참조

Hello World

일단 전체 과정을 대략 정리..
  • eclipse를 실행한다.
  • android sdk 경로를 설정한다.
    menu > Window > Preferences > Android
  • 프로젝트를 만든다.
    1. menu > File > New Project > Android
    2. Project name, Build Target, Application name 등을 설정한다.
  • 코드 생성 : src > joinc.example > hello.java

    package joinc.example;  import android.app.Activity; import android.os.Bundle; import android.widget.TextView;    public class hello extends Activity {     /** Called when the activity is first created. */     @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         TextView tv = new TextView(this);         tv.setText("Hello, Android");         setContentView(tv);     } }  
  • 실행 : Run > Run 후 Android Application을 선택한다. 그러면 Android 애뮬레이터가 뜨고, 부팅 과정을 거친후에 hello world 애플리케이션이 실행되는걸 볼 수 있다.

다음은 실행 화면


금방이네.. hello world를 찍었으니, 절반은 한 건가 ?

LayOut 편집


string resource 편집

프로그램에서 사용되는 다양한 자원들(프로그램 타이틀명, 각종 문자열등)은 XML데이터로 저장된다. 에디터로 XML 데이터를 편집하는 것으로 이들 자원의 값을 변경하거나 추가할 수 있다.
  • res/values/strings.xml
혹은 eclips ADT 플러그인 기능을 활용해도 된다. eclipse에서 해당 파일을 클릭하면, widzard 형식의 에디터로 값을 편집할 수 있다.

'Computer Science' 카테고리의 다른 글

Beginner iPhone SDK Hello World Tutorial [Example & Code]  (0) 2010.01.17
안드로이드 구조분석 wiki  (3) 2010.01.10
룩업 테이블  (0) 2010.01.09
EMACS 메뉴얼  (0) 2010.01.03
안드로이드 프로그래밍 개요  (0) 2010.01.03

넥슨별 생활이란....







'사이버탐험기' 카테고리의 다른 글

넥슨의 별나라 이야기!!!!!  (0) 2010.01.23
넥슨별 레벨업!!!!  (0) 2010.01.17
꿈의 별! 넥슨별!  (0) 2010.01.03
IMVU 라는 인터넷 데이트 장소  (0) 2010.01.03
SL 여행기2  (0) 2010.01.01

9-3-라.룩업 테이블

임의의 날짜가 주어졌을 때 이 날짜 다음의 날짜, 즉 내일을 구하는 예제를 만들어 보자. 내일이란 굉장히 쉽게 구할 수 있을 것 같지만 날짜라는 정보의 구조가 간단하지 않기 때문에 생각보다 훨씬 더 어렵다. 오늘 날짜가 m월 d일이라고 했을 때 대부분의 경우는 d만 1증가시키면 된다. 그러나 오늘이 월말일 경우는 d는 1이 되고 m은 1증가해야 하는데 예를 들어 3월 31일의 내일은 3월 32일이 아니라 4월 1일이다.

월이 바뀔 때도 m이 무조건 1증가되기만 하는 것은 아니다. 13월이라는 것은 없으므로 12월 다음은 1월이 되어야 한다. 오늘이 월말이라는 것을 알아 내려면 매 달마다 몇일까지 있는지를 조사해야 한다. 3월은 31일까지 있지만 4월은 30일까지밖에 없다. 이런 정보를 조사할 때도 배열을 사용할 수 있다. 다음 예제는 배열로 이 문제를 풀어본 것이다.

: PrintTomorrow

#include <Turboc.h>

void PrintTomorrow(int m, int d)

{

static int days[]={0,31,28,31,30,31,30,31,31,30,31,30,31};

if (d > days[m] || m < 1 || m > 12) {

printf("입력한 날짜가 틀렸습니다.\n");

} else {

d++;

if (d > days[m]) {

d=1;

m++;

if (m == 13) {

m=1;

}

}

printf("내일은 %d월 %d일입니다.\n",m,d);

}

}

void main()

{

int mon,day;

printf("오늘 날짜(월 일)을 공백으로 구분하여 입력해 주세요 : ");

scanf("%d%d",&mon,&day);

PrintTomorrow(mon,day);

}

PrintTomorrow 함수는 날짜를 전달하면 이 날짜의 내일을 조사하여 출력한다. 매월의 마지막 날에 대한 정보를 days라는 배열로 작성해 놓고 days의 첨자로 m을 사용하면 m월의 날 수를 쉽게 조사할 수 있다. 이런 식으로 값의 참조를 위해 사용하는 배열을 룩업 테이블(Lookup Table)이라고 한다. 만약 배열을 사용하지 않는다면 switch case문이나 여러 개의 조건문을 가지는 if문을 구성해야 할 것이다.

if (m==1 || m==3 || m==5 || m==7 || m==8 || m==10 || m==12) {

// 31일까지 있음

} else if (m==4 || m==6 || m==9 || m==11 {

// 30일까지 있음

} else {

// 28일까지 있음

}

조사 대상이 12개 정도이고 비슷한 값들을 가진다면 이 정도 조건문으로도 문제를 일단 해결할 수 있겠지만 만약 100개 정도의 불규칙한 값을 조사해야 한다면 이런 방법은 한계가 있다. 아무리 값이 많아도 또 값이 불규칙해도 룩업 테이블을 작성하면 아주 빠른 속도로 원하는 값을 찾을 수 있을 뿐만 아니라 이후 값을 수정하기도 편리하다. 값을 선택하는 기준이 정수라면 이 정수값을 첨자로 하는 룩업 테이블을 작성하고 정수를 첨자로 넣기만 하면 배열을 통해 원하는 값을 바로 찾을 수 있다.

룩업 테이블은 보통 한 함수만 사용하는데다 읽기 전용인 경우가 많으므로 static으로 선언하는 것이 좋다. 만약 static으로 선언하지 않고 단순 지역 배열로 선언한다면 함수가 호출될 때마다 이 배열을 매번 초기화해야 하는데 이는 엄청난 실행 속도의 저하를 가져온다. 배열의 크기가 크면 클수록 초기화 속도는 느려지는데 이럴 때 static 기억 부류를 사용하면 딱 한 번만 초기화하므로 속도에 유리하다.

다음 예제는 룩업 테이블의 또 다른 사용예인데 전혀 규칙성이 없는 난수중 하나를 선택한다. 발생 가능한 난수 목록을 배열에 미리 작성해 놓고 난수로 배열 첨자를 고르는 방식이다. 실행할 때마다 룩업 테이블에 있는 정수중 하나가 선택되어 출력될 것이다.

: RandTable

#include <Turboc.h>

void main()

{

int arRand[]={2,9,14,19,27};

int Num;

randomize();

Num=arRand[random(sizeof(arRand)/sizeof(arRand[0]))];

printf("생성한 난수 = %d\n",Num);

}

이런 방법을 쓰는 대신 원하는 난수를 포괄하는 범위에서 수를 하나 생성하고 조건문으로 원하는 난수 중 하나가 맞는지 점검하는 방법을 쓸 수도 있다. while문으로 조건에 맞는 난수가 나올 때까지 루프를 돌리면 언젠가는 원하는 값이 나오기는 하겠지만 루프를 여러 번 돌아야 하므로 비효율적이고 난수를 고르는 시간이 일정하지 않다. 룩업 테이블은 첨자만 난수로 선택하므로 단 한 번에 원하는 값을 고를 수 있고 난수의 목록을 편집하기도 편리하다.

다음 예제의 Congratulation 함수는 게임의 시도 회수에 따라 축하 메시지를 출력하는데 시도 회수가 적을수록 높은 점수를 부여한다. 회수별로 메시지를 다르게 출력하기 위해 switch case문을 사용했다.

: GameMessage1

#include <Turboc.h>

void Congratulation(int count)

{

switch (count) {

case 1:

puts("축하합니다. 최고 성적입니다.");

break;

case 2:

puts("대단한 성적입니다.");

break;

case 3:

puts("참 잘 하셨습니다");

break;

case 4:

puts("보통이 아니군요.");

break;

case 5:

puts("보통입니다.");

break;

case 6:

puts("조금 더 노력하셔야겠습니다.");

break;

case 7:

puts("정말 못하시는군요.");

break;

case 8:

puts("수준 이하입니다.");

break;

default:

puts("다음부터 절대로 이 게임을 하지 마세요.");

break;

}

}

void main()

{

Congratulation(3);

}

이 예제는 기능상의 문제는 전혀 없지만 길다란 switch case문이 왠지 비효율적으로 보인다. 시도 회수인 count로부터 메시지만을 구하는 룩업 테이블을 작성하면 출력문을 훨씬 간단하게 구성할 수 있으며 또한 메시지를 편집하거나 추가하기도 편리하다. 다음 예제는 똑같은 동작을 하되 룩업 테이블로 바꿔 본 것이다.

: GameMessage2

#include <Turboc.h>

void Congratulation(int count)

{

static char *Message[]={"",

"축하합니다. 최고 성적입니다.",

"대단한 성적입니다.",

"참 잘 하셨습니다",

"보통이 아니군요.",

"보통입니다.",

"조금 더 노력하셔야겠습니다.",

"정말 못하시는군요.",

"수준 이하입니다.",

"다음부터 절대로 이 게임을 하지 마세요.",

};

if (count >= 9) count=9;

puts(Message[count]);

}

void main()

{

Congratulation(3);

}

count를 첨자로 하는 문자열의 배열을 작성했는데 이 룩업 테이블도 물론 static으로 선언해야 한다. count가 0인 경우는 없으므로 빈 문자열로 초기화해 미사용으로 남겨 두었다. 메시지 문자열들이 한 곳에 모여 있으므로 소스가 훨씬 더 짧아지고 보기에도 좋다. 만약 count와 메시지가 일대일로 대응되지 않고 일정 범위별로 대응된다면 같은 메시지를 배열에 계속 나열할 필요없이 2차 룩업 테이블을 만든다. 예를 들어 1~3회는 상, 4~8까지는 중, 9~12까지는 하로 범위를 나누어 메시지를 다르게 출력하고 싶다면 다음과 같이 수정한다.

: GameMessage3

#include <Turboc.h>

void Congratulation(int count)

{

static char *Message[]={

"잘 하셨습니다.",

"보통입니다.",

"못 하는군요.",

};

static int arMes[]={0,0,0,0,1,1,1,1,1,2,2,2,2};

if (count >= 12) count=12;

puts(Message[arMes[count]]);

}

void main()

{

Congratulation(8);

}

count를 arMes 룩업 테이블에 넣어 몇 번째 메시지인가를 먼저 선택하고 이 값을 Message 배열의 첨자로 넣어 실제 메시지를 고르는 것이다. count로부터 최종 메시지가 선택되는 과정은 다음과 같다.

이렇게 하면 메시지를 출력하는데 필요한 최소한의 정보만 유지할 수 있으며 편집하기도 쉽다. count에 따른 메시지를 변경하려면 arMes배열을 편집하고 최종 메시지 문자열을 변경하려면 Message 배열을 편집하기만 하면 된다.

PrintTomorrow2

PrintTomorrow 예제는 년도에 대한 고려는 하지 않는데 년도까지 계산에 포함하면 윤년을 고려해야 한다. 윤년이란 4로 나누어 떨어지되 100으로는 나누어 떨어지지 않는 년도인데 1904년은 윤년이지만 1900년은 윤년이 아니다. 또한 100으로 나누어 떨어지는 년도라도 400으로 나누어 떨어지면 윤년이 되는데 2000년은 윤년이다. 윤년에는 2월달이 29일까지 있으므로 룩업 테이블에서 읽은 값 중 2월의 값을 수정한 후 사용해야 한다. 년, 월, 일 정보를 모두 입력받아 윤년까지 고려해서 내일 날짜를 출력하는 예제를 작성하라.

'Computer Science' 카테고리의 다른 글

안드로이드 구조분석 wiki  (3) 2010.01.10
안드로이드 wiki  (0) 2010.01.10
EMACS 메뉴얼  (0) 2010.01.03
안드로이드 프로그래밍 개요  (0) 2010.01.03
iPhone Coding Tutorial &#8211; In Application Emailing  (0) 2009.12.25

꿈의 별! 넥슨별!

별여행을 떠나자....


'사이버탐험기' 카테고리의 다른 글

넥슨별 레벨업!!!!  (0) 2010.01.17
넥슨별 생활이란....  (0) 2010.01.10
IMVU 라는 인터넷 데이트 장소  (0) 2010.01.03
SL 여행기2  (0) 2010.01.01
SL 여행기  (0) 2009.12.31

http://imvu.com 이라는 세컨드라이프에서 세분화된

아바타 데이트 사이트가 등장했군요.

트위터를 접속했다가 발견한 건데....

세컨드라이프에선 eco 시스템으로 새 삶의 방식을 창출한 것이라면...

이건 순전히 연애를 즐기기만을 위한 사이트인 듯... 그것도 아바타로...

어제 "제임스 카메론" 감독의 "아바타"를 관람햇습니다... 2010.01.02 18:30 ~ 21:20

과거에 인터넷에서 아바타 챗이라는 프로그램이 있었는데,,,

계속 엄청나게 발전한 3D 하드웨어, 소프트웨어로 점점 가상현실을 이룩하려 하네요.

과연 이 아바타 연애가어떻게 사람들의 삶을 변화시킬지가 궁금하네요....


'사이버탐험기' 카테고리의 다른 글

넥슨별 생활이란....  (0) 2010.01.10
꿈의 별! 넥슨별!  (0) 2010.01.03
SL 여행기2  (0) 2010.01.01
SL 여행기  (0) 2009.12.31
wow 탐험기2  (0) 2009.12.30

A Tutorial Introduction to GNU Emacs

Introduction and History

What GNU Emacs Is

GNU Emacs is a free, portable, extensible text editor. That it is free means specifically that the source code is freely copyable and redistributable. That it is portable means that it runs on many machines under many different operating systems, so that you can probably count on being able to use the same editor no matter what machine you're using. That it is extensible means that you can not only customize all aspects of its usage (from key bindings through fonts, colors, windows, mousage and menus), but you can program Emacs to do entirely new things that its designers never thought of.

Because of all this, Emacs is an extremely successful program, and does more for you than any other editor. It's particularly good for programmers. If you use a common programming language, Emacs probably provides a mode that makes it especially easy to edit code in that language, providing context sensitive indentation and layout. It also probably allows you to compile your programs inside Emacs, with links from error messages to source code; debug your programs inside Emacs, with links to the source; interact directly with the language interpretor (where appropriate); manage change logs; jump directly to a location in the source by symbol (function or variable name); and interact with your revision control system.

Emacs also provides mail readers, news readers, World Wide Web, gopher, and FTP clients, spell checking, and a Rogerian therapist, all of which are also useful for programming. But in this d0cument we'll concentrate on the basics of Emacs usage for programmers.

What GNU Emacs Is Not

First and foremost, GNU Emacs is not a WYSIWYG word processor. This is primarily because it's designed as a programmer's editor, but Emacs is also used to edit d0cuments by people who use non-WYSIWYG typesetters like TeX and Troff.

Actually, this is about the only thing I can think of that GNU Emacs is not.

Varieties of Emacs

Emacs is actually the name of a family of text editors that are either descended from or inspired by one another. The original Emacs was written in the programming language of the text editor TECO, and ran on DEC PDP-10s and -11's. Early on it inspired other Emacsen for Multics, and Lisp Machines.

The first Emacs for Unix machines was Gosling Emacs, which later went commercial as Unipress Emacs. GNU Emacs was written by Richard Stallman, the main author of the original TECO Emacs.

For an editor to be called "emacs" the main requirement is that it be fully extensible with a real programming language, not just a macro language. For GNU Emacs, this language is Lisp. Other Emacsen have used TECO, Scheme, a dialect of Trac called Mint, interpreted C-like languages, etc.

GNU Emacs itself runs on a large number of Unix machines, and under VMS, DOS/Windows, and OS/2, among others. GNU Emacs is currently at version 19.29; at Library Systems we have this version installed. On the AIT machines (quads, ellis, kimbark and woodlawn) the default emacs is version 18.57: a major revision behind. Version 18 is probably 92% compatible with version 19; 19 mostly adds new functionality. But some important commands were changed slightly. (However, an unsupported version of Emacs v19 is available as /usr/unsupported/gnu/bin/emacs19.)

Theory and Practice of Keyboards and Character Sets

I find that, for beginners, the most confusing thing about Emacs is the keyboard and character set. It's important to understand that, as a portable program, Emacs can't always know about all the keys on your keyboard. All Emacs commands are 8-bit ASCII characters. Some keyboards, however, have keys which don't correspond well to any particular ASCII characters. This is especially true of PC and Macintosh keyboards, when connected to a Unix machine through the intermediary of some telecommunications program, where the only data that flows between your PC and the Emacs running on the Unix box are 8-bit ASCII bytes.

For example, the typical PC keyboard has keys labelled PAGE UP and HOME, arrow keys, function keys, etc. Not only do these keys have no official ASCII values, but they generate no ASCII characters at all. The PC can distinguish between them by means of scan codes, but what happens when you're connected to a Unix machine via a telecommunications program and you type one of these keys?

Any of the following things can happen, depending on the telecommunications program:

  1. No ASCII character is sent at all;
  2. One ASCII character is sent, but it's an arbitrary one likely to be different under another telecommunications program;
  3. Some escape sequence is sent.

The characters generated by different keys can vary even within the same telecommunications program depending on what terminal emulation is chosen. In fact, the telecommunications program can even change the characters sent by keys that do have official ASCII characters associated with them (control-@ is a common problem).

Finally, the operating system and even terminal concentrators can muddy things further. Emacs (by default only) expects that the full ASCII character set is available. But the OS or some mux may be usurping some of your characters. The best examples are control-S and control-Q, which are sometimes used for flow control. These are important Emacs commands and you should make sure that neither your telecommunications program nor your terminal concentrator are grabbing them (Emacs can handle the OS). Other examples are nulls, sometimes swallowed up whole, and characters with the high-order bit set, sometimes stripped, or -- worse -- used for parity. Any internationalized system (like modern Unixes) work best with 8-bit no parity data channels anyway.

There's nothing Emacs can do about any of the above: it only sees 8-bit ASCII characters given to it by the operating system. But if you understand your telecommunications program, you won't have any problems with Emacs and keystrokes.

Note: Emacs actually can use special keys like the arrow keys under certain circumstances (like under X or when running natively under DOS, where Emacs understands keyboard events). But I recommend not using these keys even if they work, so that you can use Emacs from any terminal.

Notation

In the rest of this d0cument I use the standard Emacs notation to describe keystrokes:
C-x
For any x, the character Control-x.
M-x
For any x, the character Meta-x (see below for more details on Meta characters).
C-M-x
For any x, the character Control-Meta-x.
RET
The return key (C-m actually).
SPC
The space bar.
ESC
The escape key, or, equivalently, C-[

Emacs Command Structure

For Emacs, every keystroke is actually a command, even simple keystrokes like the letters A and z: printing characters are commands to insert themselves. Non-printing characters are editing commands, which might move the cursor, scroll some text, delete or copy text, etc.

Every command has a long name, which you can look up in the d0cumentation, like kill-line, delete-backward-char, or self-insert-command. These commands are bound to keystrokes for convenient editing. We call such a pairing of keystroke and command a key binding, or binding for short.

The set of all bindings make up the Emacs command set. However, Emacs is an extensible, customizable editor. This means that:

  • Bindings can be different in different modes by virtue of extensibility
  • Bindings can be different for different users by virtue of customizability

In this d0cument I describe the standard Emacs key bindings.

Simple Keys

There are 95 different printable ASCII characters, and they are all bound to self-insert-command so that they insert themselves as text when typed. For editing commands, Emacs uses all the control characters: C-a, C-b, etc. But this is only 32 more characters, and Emacs has more than 32 editing commands.

The 128 characters in the upper half of ASCII are not taken yet, but how do you type them? Emacs uses a Meta key, which works exactly like a Control key or a Shift key in that it generates no character by itself, but rather modifies another character on the keyboard. The Meta key actually generates the same character that the key it's used with generates, but with the high-order bit set. This gives us access to characters such as M-a, M-b, etc. (There's also M-A, which is a distinct character, but to minimize confusion the uppercase metacharacters are equated to the corresponding lowercase metacharacter.)

What about the control characters with the high-order bit set? These are valid metacharacters as well; they are notated C-M-a, etc. To key them you hold down Control and Meta simultaneously and strike the desired key. Because both Control and Meta are shift keys, C-M-a is the same key (and the same ASCII character) as M-C-a. But for consistency we always write the former.

Prefix or Compound Keys

The Control and Meta keys plus the printing characters give us 256 possible keystrokes, or 160 editing commands after eliminating the self-inserting characters. But Emacs has many more than 160 commands! To handle this we also use prefix commands. A prefix command is a keystroke that, when typed, waits for another character to be typed, making a pair of keystrokes bound to one command. Each prefix command adds another 256 keystrokes that we can bind commands to. Prefix commands often group together commands that are somehow related.

The standard prefix commands are:

C-c
Used for commands that are specific to particular modes, so they are free to be used for different commands depending on context. These are the most variable of Emacs commands.
C-h
Used for Help commands.
C-x
This prefix is used mostly for commands that manipulate files, buffers and windows.

These prefixes give us another 768 keystrokes, for a total 928. But Emacs has far more than 928 commands! To handle this, you can bind one of the subcommands of a prefix command to another prefix command, like C-x 4 for example, or C-x v, each such binding yielding another 256 keystrokes. A number of these two-character prefixes exist, but they're rather specialized, and don't contain a full set of 256 commands (usually there are only three or four, and the prefix is just used for a mnemonic grouping). There are even three character prefixes, but most people won't admit to using them.

Using Extended Commands

But now we're entering a sort of rarefied atmosphere: even an Emacs geek like myself doesn't really use all these key bindings. Some Emacs commands are used very rarely, and, when you need it, it's easier to look up the long name of the command (using Info, Emacs' online searchable help system) and type it directly.

There's one Emacs command that can be used to execute any other command by typing it's long name: M-x. When you type M-x Emacs prompts you for the name of any command, and then executes it.

The ESC Prefix

There's one other prefix command that's both very important and completely redundant: the ESC prefix.

Not all keyboards provide a Meta key that sets the high order bit. On a PC running Emacs natively, the ALT key is used for Meta. But when using a PC to talk to a Unix box via some telecommunications program -- well, you guessed it -- the ALT key may not work for this.

But if you have no Meta key, all is not lost. You just use the ESC prefix. M-a becomes ESC a; C-M-f becomes ESC C-f (remember the equivalence of C-M-f and M-C-f and this will make sense).

There's only one trick: ESC is not a shift key. It's actually an ASCII character, not a key modifier. This means that you don't try to hold down ESC at the same time as the other key: use it as a prefix character and type it separately and distinctly. If you lean on it it's likely to autorepeat (like any other key) and you'll get very confused.

A true Meta is a wonderful thing for Emacs (it makes typing much faster), but I used ESC for years with no trouble.

Too Many Commands?

How does anyone remember all these commands? Simple: you don't. Every Emacs user knows a different set of commands. I've used Emacs for 20 years (starting with the original TECO Emacs), and I learn useful new Emacs commands all the time. Often I notice another Emacs user doing something and I have no idea how they've done it, so I ask and learn some Emacs command that I just never came across, or never developed as a habit.

Some Emacs users just learn the basics and are completely happy. Most users learn the basics and then some advanced commands that suit their needs. Some users are constantly learning new commands to speed their editing. A few users progress to writing their own totally new Emacs commands.

Files, Buffers and Windows

Emacs has three data structures (actually four) that are intimately related, and very important to understand:
File
A file is the actual Unix file on disk. You are never editing this file. Rather, you can read a copy into Emacs to initialize a buffer, and write a copy of a buffer out to a file to save it.
Buffer
A buffer is the internal data structure that holds the text you actually edit. Emacs can have any number of buffers active at any moment. Most, but by no means all, buffers are associated with a file. Buffers have names; a buffer that has been initialized from a file is almost always named for that file, and we say that the buffer is visiting the file. This means, in particular, that when you save the buffer, it's saved to the proper file. At any given time exactly one buffer is selected: this is the buffer that your hardware cursor is in, and this is where commands you type take effect (including self-insert commands). Buffers can be deleted at will; deleting a buffer in no way deletes the file on disk (though you may lose any editing changes you made if you don't save first).
Window
A window is your view of a buffer. Due to limited screen real-estate, you may not have room to view all your buffers at once. You can split the screen, horizontally or vertically, into as many windows as you like (or at least have room for), each viewing a different buffer. It's also possible to have several windows viewing different portions of the same buffer. Windows can be created and deleted at will; deleting a window in no way deletes the buffer associated with the window. Each window has its own Mode Line, but there's still only one minibuffer.
Frame
A frame is like a window, but is treated as a separate entity under a windowing system like X. I won't be discussing frames.

Commands to Manipulate Files

C-x C-f
find-file. This is the main command used to read a file into a buffer for editing. It's actually rather subtle. When you execute this command, it prompts you for the name of the file (with completion). Then it checks to see if you're already editing that file in some buffer; if you are, it simply switches to that buffer and doesn't actually read in the file from disk again. If you're not, a new buffer is created, named for the file, and initialized with a copy of the file. In either case the current window is switched to view this buffer.
C-x C-s
save-buffer. This is the main command used to save a file, or, more accurately, to write a copy of the current buffer out to the disk, overwriting the buffer's file, and handling backup versions.
C-x s
save-some-buffers. Allows you to save all your buffers that are visiting files, querying you for each one and offering several options for each (save it, don't save it, peek at it first then maybe save it, etc).

Commands to Manipulate Buffers

C-x b
switch-to-buffer. Prompts for a buffer name and switches the buffer of the current window to that buffer. Doesn't change your window configuration. This command will also create a new empty buffer if you type a new name; this new buffer will not be visiting any file, no matter what you name it.
C-x C-b
list-buffers. Pops up a new window which lists all your buffers, giving for each the name, modified or not, size in bytes, major mode and the file the buffer is visiting.
C-x k
kill-buffer. Prompts for a buffer name and removes the entire data structure for that buffer from Emacs. If the buffer is modified you'll be given an opportunity to save it. Note that this in no way removes or deletes the associated file, if any.
C-x C-q
vc-toggle-read-only. Make a buffer read-only (so that attempts to modify it are treated as errors), or make it read-write if it was read-only. Also, if the files is under version control, it will check the file out for you.

Commands to Manipulate Windows

C-v
scroll-up. The basic command to scroll forward (towards the end of the file) one screenful. By default Emacs leaves you two lines of context from the previous screen.
M-v
scroll-down. Just like C-v, but scrolls backwards.
C-x o
other-window. Switch to another window, making it the active window. Repeated invocation of this command moves through all the windows, left to right and top to bottom, and then circles around again. Under a windowing system, you can use the left mouse button to switch windows.
C-x 1
delete-other-windows. Deletes all other windows except the current one, making one window on the screen. Note that this in no way deletes the buffers or files associated with the deleted windows.
C-x 0
delete-window. Deletes just the current window, resizing the others appropriately.
C-x 2
split-window-vertically. Splits the current window in two, vertically. This creates a new window, but not a new buffer: the same buffer will now be viewed in the two windows. This allows you to view two different parts of the same buffer simultaneously.
C-x 3
split-window-horizontally. Splits the current window in two, horizontally. This creates a new window, but not a new buffer: the same buffer will now be viewed in the two windows. This allows you to view two different parts of the same buffer simultaneously.
C-M-v
scroll-other-window. Just like C-v, but scrolls the other window. If you have more than two windows, the other window is the window that C-x o would switch to.

Fundamental Concepts

It's probably more important to understand these fundamental Emacs concepts than it is to understand any of the actual editing commands. The editing commands are details: you can learn them easily on your own if you get the groundwork right.

Entering and Exiting

To enter Emacs, you just say:
    emacs
when it comes up, you won't be editing any file. You can then use the file commands to read in files for editing. Alternatively, you can fire up Emacs with an initial file (or files) by saying:
    emacs foo.tcl

To exit Emacs, use the command C-x C-c (which is bound to save-buffers-kill-emacs). It will offer to save all your buffers and then exit.

You can also suspend Emacs (in the Unix sense of stopping it and putting it in the background) with C-x C-z (which is bound to suspend-emacs). How you restart it is up to your shell, but is probably based on the fg command.

Self Inserting Commands

Once you've got Emacs running, you can type into it. There's no need for any special insert mode or anything like that: remember, printing characters insert themselves because each one is bound to self-insert-command.

The Screen

The Mode Line

The Emacs screen is completely devoted to the text of your file, except for one line near the bottom of the screen: the Mode Line. This line is informational: you can never move into it. It's almost always in reverse video or otherwise highlighted. It displays important information (which may change), including:
  • The state of the buffer, one of modified (indicated by a pair of asterisks), unmodified (hyphens), or read-only (indicated by a pair of % signs).
  • The name of the file you're editing (it will be *scratch* if you're not editing any file).
  • The major mode (in parens).
  • The amount of the file that you can see on the screen:
    All
    You can see all of the file.
    Top
    You can see the top of the file.
    Bot
    You can see the bottom of the file.
    Percentage
    NN% indicates the percentage of the file above the top of the window.

The Minibuffer

The blank line below the mode line is the minibuffer. The minibuffer is used by Emacs to display messages, and also for input when Emacs is prompting you to type something (it may want you to type yes or no in answer to a question, the name of a file to be edited, the long name of a command, etc).

The minibuffer is also known as the echo area, because Emacs echoes keystrokes here if you're typing really slowly. To see this, type any multi-character keystroke (like, ESC q) with a long pause between the keystrokes.

Strange Messages

Emacs will occasionally print messages in the minibuffer of its own accord, seemingly unrelated to what you're doing. The two most common messages are "Mark set" and "Garbage collecting...". The former means that Emacs has set the mark for you as a result of your last command; automatic mark setting is a convenient feature of some commands; see The Mark and The Region. The latter means that Emacs' lisp engine is reclaiming storage. You can just ignore it and keep typing, if you like: Emacs won't lose your characters.

Funny Characters

When your file contains control characters or characters with the high-order bit set, Emacs displays them as a backslash followed by three octal digits (where the digits give the ASCII value of the character). You'll notice that there's no ambiguity here: Emacs can tell the difference between a funny character and the four characters backslash digit digit digit. (You can't move the cursor between the digits of a funny character.) Note that if your terminal or windowing system is known to be able to display an 8-bit character set, like ISO Latin-1, Emacs will display those characters rather than the octal digits.

Long Lines

Emacs doesn't break lines for you automatically, unless you ask it to. By default it lets lines be as long as you type them. More importantly, it doesn't mess with long lines in files that you may read in. (Some editors, like old versions of vi, truncate long lines.)

It may seem annoying to have to hit return at the end of long lines, but this is actually just the default for certain modes. The reason for this is that Emacs is a programmer's editor, and any editor that will insert line breaks without your telling it to isn't safe for editing code or data. In modes oriented towards text, Emacs does insert line breaks for you automatically.

Eight Bit Clean

Emacs is eight bit clean, meaning you can edit binary files without corruption. (Some editors, like old versions of vi, corrupt certain characters, notably nulls and characters with the high bit set.)

Interrupting and Aborting

Sometimes Emacs will do something that you don't understand: it will prompt you for some information, or beep when you try to type, or something equally confusing. This just means that you've typed some command unwittingly (hitting a random function key is a good way to demonstrate this).

When this happens, you just need to type C-g (which is bound to keyboard-quit). This is the ASCII BEL character, and so C-g is sort of mnemonic for ringing the bell, which is what it does. But it also does something very important: it interrupts what Emacs is doing. This will get you out of any questions that Emacs may be asking you, and it will abort a partially typed key sequence (say if you typed C-x by mistake).

Because Emacs is fully recursive, you may occasionally need to type C-g more than once, to back out of a recursive sequence of commands. Also, if Emacs is really wedged (say, in a network connection to some machine which is down), typing three C-g's quickly is guaranteed to abort whatever's wedging you.

Help

Emacs has extensive online help, most of which is available via the help key, C-h. C-h is a prefix key. Type C-h twice to see a list of subcommands; type it three times to get a window describing all these commands (a SPC will scroll this window). Some of the most useful help commands are:
C-h a
command-apropos. Prompts for a keyword and then lists all the commands with that keyword in their long name.
C-h k
describe-key. Prompts for a keystroke and describes the command bound to that key, if any.
C-h i
info. Enters the Info hypertext d0cumentation reader.
C-h m
describe-mode. Describes the current major mode and its particular key bindings.
C-h p
finder-by-keyword. Runs an interactive subject-oriented browser of Emacs packages.
C-h t
help-with-tutorial. Run the Emacs tutorial. This is very helpful for beginners.

Info

Emacs has a builtin hypertext d0cumentation reader, called Info. To run it, type C-h i or M-x info RET. It has it's own tutorial, which you should run the first time through by typing h. The tutorial assumes you understand about as much about Emacs as is covered in this d0cument.

Infinite Undo with Redo

One of the most important Emacs commands is undo, invoked with C-_ (control underbar). C-_ is a valid ASCII character, but some keyboards don't generate it, so you can also use C-x u -- but it's more awkward to type, since it's a two-character command.

The undo command allows you to undo your editing, back in time. It's handy when you accidentally convert all of a huge file to uppercase, say, or delete a huge amount of text. One keystroke changes everything back to normal.

We say Emacs has infinite undo because, unlike some editors, you can undo a long chain of commands, not just one previous one, even undoing through saves. We say Emacs has redo because you can reverse direction while undoing, thereby undoing the undo.

Once you get used to this feature you'll laugh at any editor that doesn't have it (unless you're forced to use it...). It's very important to get comfortable with undo as soon as possible; I recommend reading the undo section of the manual carefully and practising.

Backups and Auto Save Mode

Emacs never modifies your file on disk until you tell it to, but it's very careful about saving your work for you in a number of ways.
Backup files.
Emacs always saves the previous version of your file when you save. If your file is named foo, the backup will be called foo~ (note the squiggle). Although it is off by default, Emacs will keep any number of previous versions for you, named foo.~1~, foo.~2~, etc. You can decide how many versions are to be kept. (But Unix provides more powerful tools for managing multiple versions of files.)
Auto-Save files.
Emacs also, by default, auto-saves your file while you're editing it. The auto-save file for a file foo is called #foo#. If Emacs (or the system) were to crash before you could save your edits, you can recover almost all of it from this file. Auto-saving happens (by default) every 300 characters, or when a system error is encountered.

Completion

To save you typing, Emacs offers various forms of completion: this means Emacs tries to complete for you partially typed file names, command names, etc. To invoke completion, you usually type TAB.

Giving Commands Arguments

Many Emacs commands take arguments, exactly the way a procedure or function takes arguments in a programming language. Most commands prompt you for their arguments: e.g., a command to read in a file will prompt you for the filename.

There's one kind of argument that's so commonly accepted that there's a special way to provide it: numeric arguments. Many commands will interpret a numeric argument as a request to repeat that many times. For example, the delete-char command (bound to C-d), which normally deletes one character to the right of the cursor, will delete N characters if given a numeric argument of N. It works with self-inserting commands too: try giving a numeric argument to a printing character, like a hyphen.

To give a command a numeric argument of, say, 12, type C-u 12 before typing the command. If you type slowly, you'll see:

C-u 1 2-
in the echo area. Then type C-d and you'll have given delete-char an argument of 12. You can type any number of digits after C-u. A leading hyphen makes a negative argument; a lone hyphen is the same as an argument of -1. If you begin typing a numeric argument and change your mind, you can of course type C-g to abort it.

Since one often isn't interested in precisely how many times a command is repeated, there's a shorthand way to get numeric arguments of varying magnitudes. C-u by itself, without any subsequent digits, is equal to a numeric argument of 4. Another C-u multiplies that by 4 more, giving a numeric argument of 16. Another C-u multiplies that by 4 more, giving a numeric argument of 64, etc. For this reason C-u is called the universal-argument.

Note that commands aren't required to interpret numeric arguments as specifying repetitions. It depends on what's appropriate: some commands ignore numeric arguments, some interpret them as Boolean (the presence of numeric argument -- any numeric argument -- as opposed to its absence), etc. Read the d0cumentation for a command before trying it.

Quoting Characters That Are Bound As Commands

Sometimes one needs to insert control characters into a file. But how can you insert an ESC, say, when it's used as a prefix command? The answer is to use the command quoted-insert, which is bound to C-q. C-q acts like a prefix command, in that when you type it it waits for you to type another character. But this next character is then inserted into the buffer, rather than being executed as a command. So C-q ESC inserts an Escape.

C-q can also be used to insert characters by typing C-q followed by their ASCII code as three octal digits.

Disabled Commands

Some commands that are especially confusing for novices are disabled by default. When a command is disabled, invoking it subjects you to a brief dialog, popping up a window displaying the d0cumentation for the command, and giving you three choices:
  • Space to try the command just this once, but leave it disabled,
  • Y to try it and enable it (no questions if you use it again),
  • N to do nothing (command remains disabled).
You're very likely to encounter one particular disabled command: M-ESC (aka ESC ESC), because it's very easy to type two escapes in a row when using the Escape prefix.

Motion and Objects

One of the main things one does in an editor is move around, in order to apply editing commands. Emacs provides many motion commands, which are arranged around textual objects: for each textual object, there is typically a motion command that moves forward over such an object and backward over it (or you can think of this as moving to the beginning and to the end).

All these motion commands take numeric arguments as repetitions.

The most basic textual object is the character. Emacs understand many other objects, sometimes depending on what mode you're in (a C function textual object probably doesn't make much sense if you're not editing C source code).

The exact definition of what makes up a given textual object is often customizable, but more importantly varies slightly from mode to mode. The characters that make up a word in Text Mode may not be exactly the same as those that make up a word in C Mode for example. (E.g., underbars are considered word constituents in C Mode, because they are legal in identifier names, but they aren't considered word constituents in Text Mode.) This is extremely useful, because it means that you can use the same motion commands and yet have them automatically customized for different types of text.

Characters

C-f
forward-char. Moves forward (to the right) over a character.
C-b
backward-char. Moves backward (to the left) over a character.
The f for forward and b for backward mnemonic will reoccur.

Words

M-f
forward-word. Moves forward over a word.
M-b
backward-word. Moves backward over a word.
Note the f/b mnemonic. Also, as another mnemonic, note that M-f is like a "bigger" version of C-f.

Lines (vertically)

C-n
next-line. Moves down to the next line.
C-p
previous-line. Moves up to the previous line.
When moving by lines, the cursor tries to stay in the same column, but if the new line is too short, it will be at the end of the line instead. This is very important: Emacs doesn't insert spaces at the ends of lines (end of line is unambiguous).

Lines (horizontally)

C-a
beginning-of-line. Moves to the beginning of the current line.
C-e
end-of-line. Moves to the end of the current line.
E for end, A for the beginning of the alphabet.

Sentences

M-a
backward-sentence. Moves to the beginning of the current sentence.
M-e
forward-sentence. Moves to the end of the current sentence.
Note the mnemonic relation between C-a / M-a and C-e / M-e.

Paragraphs

M-{
backward-paragraph. Move to the beginning of the current paragraph.
M-}
forward-paragraph. Move to the end of the current paragraph.

Pages

C-x [
backward-page. Moves to the beginning of the current page.
C-x ]
forward-page. Moves to the end of the current page.
Pages are separated by formfeed characters (C-l) in most modes.

Buffers

M-<
beginning-of-buffer. Moves to the beginning of the buffer.
M->
end-of-buffer. Moves to the end of the buffer.

S-Expressions (balanced parentheses)

An S-expression (sexp for short) is the name for balanced parentheses (and the text they enclose) in Lisp. In Emacs, this useful notion is available in most modes; it's especially useful for editing programming languages. The characters that Emacs recognizes as parens are usually regular parentheses (aka round brackets), square brackets, and braces (aka curly brackets), but it depends on the mode (for some languages, angle brackets may act as parens).

But sexps are more than just balanced parens: they're defined recursively. A word that doesn't contain any parens also counts as a sexp. In most programming language modes, quoted strings are sexps (using either single or double quotes, depending on the syntax of the language). The sexp commands move in terms of all these units.

These commands may seem confusing at first, but for editing most programming languages they're fantastic. Not only do they move you around quickly and accurately, but they help spot syntax errors while you're editing, because they'll generate an error if your parens or quotes are unbalanced.

C-M-b
backward-sexp. Moves backward over the next sexp. If your cursor is just to the right of a left paren, C-M-b will beep, because there's no sexp to the left to move over: you have to move up.
C-M-f
forward-sexp. Moves forward over the next sexp. Same deal if your cursor is just to the left of a right paren.
C-M-u
backward-up-list. Move backward up one level of parens. In other words, move to the left paren of the parens containing the cursor, skipping balanced sexps.
C-M-d
down-list. Move down one level of parens. In other words, move to the right of the next left paren, skipping balanced sexps. E.g., if your cursor is sitting on the return type of a C function declaration, C-M-d moves to the inside of the formal parameter list.

Functions

Since functions are such an important unit of text in programming languages, whether they're called functions, subroutines, procedures, procs, defuns or whatever, Emacs has commands to move over them. Like the sexp commands, these commands work appropriately in most programming language modes. Emacs calls this generic notion of function or procedure defun, again after Lisp.
C-M-a
beginning-of-defun. Move to the beginning of the current defun.
C-M-e
end-of-defun. Move to the end of the current defun.
Note the mnemonic analogy with lines and sentences.

Deleting, Killing and Yanking

Emacs' deletion commands are also based on the textual objects above. But first, a terminological distinction: Deletion means to remove text from the buffer without saving it; most deletion commands operate on small amounts of text. Killing means to save the removed text, so that it can be yanked back later someplace else.

Killed text is saved on the kill ring. The kill ring holds the last N kills, where N is 30 by default, but you can change it to anything you like by changing the value of the variable kill-ring-max. The kill ring acts like a fifo when you're killing things (after the 30th kill, kill number one is gone), but like a ring when you're yanking things back (you can yank around the ring circularly). kill-ring-max doesn't apply to the amount of text (in bytes) that can be saved in the kill ring (there's no limit), only to the number of distinct kills.

Characters

C-d
delete-char. Deletes the character to the right of (under, if the cursor is a block that covers a character) the cursor.
DEL
delete-backward-char. Deletes the character to the left of the cursor.
Remember, Emacs does not use C-h (aka Backspace) for deletion, but for help! Depending on your cultural background, this may well be the single hardest thing to learn about Emacs. Why does Emacs make this choice? Well, since there's no need for two commands to delete one character backward, and since DEL (aka Delete) can only be mnemonic for deletion while C-h is a nice mnemonic for help, the choice was made. Me, I've never used C-h to delete, so it suits me fine.

Words

M-d
kill-word. Kills to the end of the word to the right of the cursor (forward).
M-DEL
backward-kill-word. Kills to the beginning of the word to the left of the cursor (backward).

Lines (vertically)

It doesn't seem too intuitive to kill lines vertically by analogy with C-n and C-p; I know of no such commands.

Lines (horizontally)

C-k
kill-line. Kills to the end of the current line, not including the newline. Thus, if you're at the beginning of a line it takes two C-k's to kill the whole line and close up the whitespace.
C-u 0 C-k
kill-line. Kills to the beginning of the current line, not including the newline.
You might think that C-u -1 C-k would be used to kill to the beginning of the line, and it does, but it includes the newline before the line as well.

Sentences

M-k
kill-sentence. Kills to the end of the current sentence, including any newline within the sentence.
C-u -1 M-k
kill-sentence. Kills to the beginning of the current sentence, including any newlines within the sentence.

Paragraphs

The commands forward-kill-paragraph and backward-kill-paragraph exist, but are not bound to any keys by default.

Pages

There are no commands to kill pages (but see The Mark and the Region).

Buffers

The command kill-buffer doesn't kill all the text in the buffer, but rather the entire buffer data structure; see The Mark and the Region.

S-Expressions (balanced parentheses)

C-M-k
kill-sexp. Kills the sexp after the cursor.
C-u -1 C-M-k
kill-sexp. Kills the sexp before the cursor.
The command backward-kill-sexp exists, but is not bound to any key by default.

Functions

There are no commands to kill functions (defuns) (but see The Mark and the Region).

Extending Kills

If you kill several times in a row, with any combination of kill commands, but without any non-kill commands in between, these kills are appended together in one entry on the kill ring. For example you can kill a block of text as several lines by saying C-u 6 C-k, which kills (as one kill) 6 lines.

Yanking

Once you've killed some text, how do you get it back? You can yank back the most recently killed text with C-y (yank). Since Emacs has only one kill ring (as opposed to one per buffer), you can kill in one buffer, switch to another and yank the text there.

To get back previous kills, you move around the kill ring. Start with C-y to get the most recent kill, and then use M-y to move to the previous spot in the kill ring by replacing the just-yanked text with the previous kill. Subsequent M-y's move around the ring, each time replacing the yanked text. When you reach the text you you're interested in, just stop. Any other command (a motion command, self-insert, anything) breaks the cycling of the kill ring, and the next C-y yanks the most recent kill again.

Copying and Moving Text

Emacs has no need for special commands to copy or move text; you've already learned them! To move text, just kill it and yank it back elsewhere. To copy text, kill it, yank it back immediately (so it's as if you haven't killed it, except it's now in the kill ring), move elsewhere and yank it back again. For commands to copy and move arbitrary regions of text, as opposed to textual objects, see The Mark and The Region.

Searching and Replacing

Emacs has a variety of unusual and extremely powerful search and replace commands. The most important one is called incremental search. This is what the command isearch-forward, bound to C-s, does: it searches incrementally, one character at a time, as you type the search string. This means that Emacs can often find what you're looking for before you have to type the whole thing. To stop searching, you can either hit RET or type any other Emacs command (which will both stop the search and execute the command). You can search for the next match at any point by typing another C-s at any point; you can reverse the search by typing C-r; and you can use DEL to delete and change what you're searching for.

isearch-backward, bound to C-r, works the same way, but searches backward. (Use C-r to search for the next match and C-s to reverse the search.)

Occasionally you may want to search non-incrementally (though I rarely do). You can do this by typing C-s RET text RET, where text is the text to search for.

Much more useful is word search, which lets you search for a sequence of one or more words, regardless of how they're separated (e.g, by any number and combination of newlines and whitespace). To invoke word search, type C-s RET C-w word word word RET.

Emacs can also search incrementally (or not) by regular expressions; this is an extremely powerful feature, but too complex to describe here.

Replacement

Emacs' most important command for replacing text is called query-replace (bound to M-%). This command prompts you for the text to replace, and the text to replace it with, and then searches and replaces within the current buffer. query-replace is interactive: at each match, you are prompted to decide what to do; you have the following options:
SPC
Perform this replacement.
DEL
Don't perform this replacement.
RET
Terminate query-replace without performing this replacement.
ESC
Same as RET.
.
Perform this replacement but then terminate the query-replace.
!
Perform this replacement and all the rest in the buffer without querying (ie unconditionally).
There are many more subcommands, but they require more Emacs expertise to understand them.

There are also more replacement commands you should look into, including replace-string (simple unconditional replacement), replace-regexp and query-replace-regexp (which use regular expressions), and tags-query-replace, which replaces all identifiers in a collection of source code files.

query-replace and the other replacement commands are, by default, smart about case. For example, if you're replacing foo with bar and find Foo, Emacs replaces it with Bar; if you find FOO, Emacs replaces it with BAR, etc.

The Mark and The Region

Emacs can manipulate arbitrary chunks of text as well as distinct textual objects. The way this is done is to define a region of text; many commands will operate on this region.

The region is the text between point and mark. Point is actually the Emacs term for what we've been calling the cursor up to now. The mark, on the other hand, is set with a special command C-@ (set-mark-command). This sets the mark exactly where point is, but now you can move point elsewhere and you have: the region.

Each buffer has a distinct point and mark, and therefore a distinct region. (It's also possible for there to be no mark in a buffer, and therefore no region.)

The region is the same regardless of whether point comes first in the buffer or mark does; it makes no difference, just do what's convenient.

The region is normally invisible (but see C-x C-x). You'll get used to this. However, if you're running Emacs under a windowing system, you can make the region visible by executing M-x transient-mark-mode.

Many commands that move point a significant distance (like M-< and C-s, for example) leave the mark set at the spot they moved from. You'll see "Mark set" in the echo area when this happens.

When using Emacs under a windowing system like X, the mouse can be used to sweep out the region, but many Emacsers find it faster to keep their hands on the keyboard and use the familiar motion commands.

There are some special commands that are specifically designed to set the region around some interesting text.

M-@
mark-word. Sets the region around the next word, or from point to the end of the current word, if you're in the middle of one.
M-h
mark-paragraph. Sets the region around the current paragraph.
C-M-@
mark-sexp. Sets the region around the same sexp that C-M-f would move to.
C-M-h
mark-defun. Sets the region around the current defun.
C-x C-p
mark-page. Sets the region around the current page.
C-x h
mark-whole-buffer. Sets the region around the entire buffer.

So now you know how to define the region: what can you do with it?

C-x C-x
exchange-point-and-mark. Swaps mark and point. Repeated rapid execution of this command makes it easy to see the extent of the region.
C-w
kill-region. Kills the region. It goes on the kill ring, of course.
M-w
kill-ring-save. Saves the region to the kill ring without removing it from the buffer. This is exactly equivalent to typing C-w C-y.
C-x C-i
indent-rigidly. Rigidly indents the region by as many characters (columns) as you provide as a numeric argument (default is 1 column).
C-x C-l
downcase-region. Convert the entire region to lowercase. This command is disabled by default.
C-x C-u
upcase-region. Convert the entire region to uppercase. This command is disabled by default.
M-x fill-region
fill-region. Fills, i.e., justifies with a ragged right margin, all the paragraphs within the region.
There are many, many more.

Indentation

In programming language modes, Emacs uses the TAB key to indent a line automatically, in accordance with indentation rules for your programming language. For example, in C Mode Emacs understands if, while, do, for, functions, switch, etc and indents appropriately. Of course, there are no hard and fast rules for indentation in most languages, so Emacs allows you to customize the indentation for your own style.

Modes

The main way Emacs customizes commands for different kinds of text is through major and minor modes. Every buffer has a major mode, and may have zero or more minor modes. Sometimes Emacs chooses a major mode for you automatically, typically based on a file extension (e.g., files ending in .c will automatically be in C Mode; files ending in .tcl will automatically be in Tcl Mode). But you can always set the mode explicitly.

Some Major Modes

Fundamental Mode
The basic mode in reference to which all specialized modes are defined. Perfectly fine for editing any kind of text, just doesn't provide any special features.
Text Mode
For editing text. Has special commands for spell-checking, centering lines, etc.
Outline Mode
For editing a stylized type of outline. Implements folding of outline levels, etc.
Lisp Mode
For editing Common Lisp source code. Has an interactive link to a Common Lisp interpreter in another buffer.
Tcl Mode
For editing Tcl source code. Has an interactive link to a Tcl interpreter in another buffer.
C Mode
For editing C source code. Has special indentation, etc.
There are many other major modes, some very specialized (e.g., modes for editing sending email, reading Usenet news, browsing directories, browsing the World Wide Web, etc).

Further Information

GNU Emacs Frequently Asked Questions List

The GNU Emacs FAQ is very well done; I recommend it highly.

Info

Don't forget that the complete text of the GNU Emacs Manual is available via Info, Emacs' hypertext d0cumentation reader.

Usenet Newsgroups

Only a selection of some of the Emacs-related Usenet newsgroups.
gnu.emacs.help
Help for users' GNU Emacs problems, answered by your peers.
comp.emacs
General coverage of all Emacs-like editors.
gnu.emacs.announce
Announcements of new versions of GNU Emacs, etc.
alt.religion.emacs
Emacs as religion. Official home of the perennial flame wars.
gnu.emacs.sources
Postings of source code for new GNU Emacs programs.

Bibliography

  • Richard M. Stallman. GNU Emacs Manual. Cambridge, MA: Free Software Foundation, [n.d.]. The authoritative user's reference; also a fine introduction. The complete text is available on the Web and via Info.
  • Debra Cameron and Bill Rosenblatt. Learning GNU Emacs. Sebastopol, CA: O'Reilly and Associates, 1991. A good introduction. Covers version 18 only.
  • Michael A. Schoonover et al. GNU Emacs: Unix Text Editing and Programming. Reading, MA: Addison-Wesley, 1992.
  • Bill Lewis, Dan LaLiberte, and the GNU Manual Group. GNU Emacs Lisp Reference Manual. Cambridge, MA: Free Software Foundation, 1993. Covers version 19 Elisp. Only if you want to learn to program in Emacs Lisp. The complete text is available on the Web and via Info.
  • Richard M. Stallman. "EMACS: The Extensible, Customizable, Self-Documenting Display Editor". In Interactive Programming Environments, edited by David R. Barstow, Howard E. Shrobe, and Erik Sandewall. New York: McGraw-Hill, 1984. An interesting article on the design of Emacs. Predates GNU Emacs; covers the original TECO Emacs and Lisp Machines Emacsen.

Keith Waclena
The University of Chicago Library

This page last updated: Tue Feb 3 23:37:14 CST 2009

'Computer Science' 카테고리의 다른 글

안드로이드 wiki  (0) 2010.01.10
룩업 테이블  (0) 2010.01.09
안드로이드 프로그래밍 개요  (0) 2010.01.03
iPhone Coding Tutorial &#8211; In Application Emailing  (0) 2009.12.25
Introduction to MapKit in iPhone OS 3.0  (0) 2009.12.25

How to Program Google Android
By Reto Meier

So you saw the Android announcement and decided you wanted a piece of that US$10million in prize money huh? In the week since the SDK was released more than 4,300 people have joined the Android support forum posting more than 4,000 messages between them. Robert Scoble doesn't know a single developer playing with Android – perhaps Scoble doesn't hang around with many developers?

I wanted to give the SDK a good work-out so my application uses the GPS, the address book, and has a map.

The only way to judge an SDK is getting in there and writing an application that does something cool, so I'll take you through the development process for my first Android application: Where Are My Friends?

WamF shows how far away you are right now from all the people in your address book, plots you and them on a map, and draws lines between you and any friends nearby.

WamF is pretty simple but it makes use of some of the more interesting features of Android – Location Based Information (GPS etc), maps, the contacts manager, and the phone dialer. Total development time from hitting Download on the SDK page was about 14 hours (spread over two mornings and evenings).

My Android development is in Windows with Eclipse using the plugin, so I will assume you're doing the same.

Before I get started here's a bit on my background. I've mentioned before that I'm a C# .NET desktop applications developer in my real life. It's been almost 10 years since I've done anything with Java and I've never done any mobile phone development. With Android I develop in Windows with Eclipse using the Android plugin.

Let's start by downloading Eclipse and unzipping it into a new folder. Then download the Android SDK and unzip that into another new folder. Open Eclipse and create a new workspace for Android development.

Install the Android Plugin by selecting Help > Software Updates > Find and Install..., and in the dialog box choose Search for new Features to install. Select New Remote Site and enter https://dl-ssl.google.com/android/eclipse/. into the dialog box. Hit OK and accept all the prompts until it's installed. Restart Eclipse and you're almost ready to rock.

Select Window > Preferences... and select Android, then put the folder where you unzipped the SDK into the SDK Location text box. Hit Apply then OK and you're done.

The tutorial and exercises are useful. Do them.

Let's make sure everything's installed right by creating the Hello Android demo. The Android team have a detailed description of how to do this so I won't repeat it here. It's worth checking out the known bugs if you encounter any problems.

The Android d0cumentation is excellent; after you've finished the Hello Android project run through the exercises. They're easy to follow and give a good idea of how a 'real' application fits together.

Design a UI, leveraging one of the sample projects

Onto business. Step one should always be UI design. Figure out what it is you want to tell the user and what actions they'll need then develop an interface that will make this as intuitive as possible. To keep things simple I'm going to base my new project on the NotePad project used in the tutorial exercises.

I'll start by changing the resource strings to change the name of the app, and modifying the menu options .

Use the Location Based Services to figure out where we are and request updates when we move

Possibly the most enticing of the Android features are the Location Based Services that give your application geographical context through Location Providers (GPS etc). Android includes a mock provider called 'gps' that marches back and forth through San Fransisco. Alternatively you can create your own mock providers in XML.

You use the LocationManager to find your current position.

    locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); Location location = locationManager.getCurrentLocation("gps");

Iterate over the address book pulling out names, locations, and phone numbers

A less publicized feature of Android is the ability to share content between applications. We're going to use this feature to populate our List with our contacts' names and their current distance from our phone so we create an updateList method that we call after we've gotten our current location.

Use the ContentResolver to return a query that provides access to data shared using Content Providers. Queries are returned as cursors that provide access to the underlying data tables. The data we're interested in is accessed using the People content provider.

    Cursor c = getContentResolver().query(People.CONTENT_URI, null, null, null, null); startManagingCursor(c);

The Cursor is a managed way of controlling your position (Row) in the underlying table. We get access to the data by specifying the column that holds the information we're after. Rather than memorising the column index for each Content Provider we can use constants from the People class as a shortcut.

    int coordIdx = c.getColumnIndex(People.NOTES); int phoneIdx = c.getColumnIndex(People.PhonesColumns.NUMBER); int nameIdx = c.getColumnIndex(People.NAME);

Now iterate over the table using the cursor storing the results in arrays. You'll note that we're pulling our contacts' location from the Notes field. In reality we'd want to figure this out based on their address using a geocoding lookup.

    List listItems = new ArrayList();

    c.first();
    do {
      String name = c.getString(nameIdx);
      String coords = c.getString(coordIdx);
      String phone = c.getString(phoneIdx);

      ... [ Process the lat/long from the coordinates ] ...
      ... [ Storing their location under variable loc ] ...

      String distStr = String.valueOf(location.distanceTo(loc)/1000);
      name = name + " (" + distStr + "km)";
      listItems.add(name);

      numbers.add("tel:" + phone);
    } while(c.next());

Then we assign our list of strings to the array using an ArrayAdapter.

    ArrayAdapter notes = new ArrayAdapter(this, R.layout.notes_row, items);
    setListAdapter(notes);

Refresh our list when we move

Given the location sensitive nature of WamF it makes sense to update the display whenever we move. Do this by asking the LocationManager to trigger a new Intent when our location provider notices we've moved.

    List providers = locationManager.getProviders();
    LocationProvider provider = providers.get(0);
    Intent intent = new Intent(LOCATION_CHANGED);
    locationManager.requestUpdates(provider, minTime, minDistance, intent);

Intents in Android are like events in traditional event driven programming, so we're triggering a LOCATION_CHANGED event/intent every time we move by a minimum distance after a minimum time. The next step is to create an IntentReceiver (event handler), so create a new internal class that extends IntentReceiver and override the ReceiveIntent event to call our update method.

    public class myIntentReceiver extends IntentReceiver {
      @Override
      public void onReceiveIntent(Context context, Intent intent) {
        updateList();
      }
    }

We then have our activity listen for a LOCATION_CHANGED intent by registering the event handler and specifying the intent it should be listening for (LOCATION_CHANGED). Do this in the onCreate method or create a new menu option to start/stop the automatic updates.

    filter = new IntentFilter(LOCATION_CHANGED);
    receiver = new myIntentReceiver();
    registerReceiver(receiver, filter);

Keep your phone running light by registering / unregistering the receiver when the activity Pauses and Resumes – there's no point in listening for location changes if we can't see the list.

Set up a map activity and create an overlay to show where you are in relation to your friends

Half of the fun in having location sensitive information is drawing it on a map. Create a new activity class to display a map centered on our current location with markers at our friends locations. While we're at it we can draw a line from our position to each of our friends.

The map control itself is called a MapView, but we can only use a MapView in a MapActivity, so we'll change the inheritance of this activity to MapActivity.

    public class MyMapViewActivity extends MapActivity

To display the map we need to create a new MapView and set it as the content for our activity in the OnCreate method.

    MapView mapView = new MapView(this);
    setContentView(mapView);

This will make the MapView fill the entire screen, so use views like LinearLayout if we want to create a more complicated UI layout.

We'll want to get access to the OverlayController and MapController, so create global variables to store them and assign the references within the OnCreate method. We'll also be using the Location information, so get a reference to that too. With the references assigned set your map zoom and starting location using the MapController. When you're finished OnCreate should look something like this.

    protected void onCreate(Bundle icicle) {
      super.onCreate(icicle);
      MapView mapView = new MapView(this);
      mapController = mapView.getController();
      overlayController = mapView.createOverlayController();
      locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
      mapController.zoomTo(9);
      setContentView(mMapView);
      updateView();
    }

updateView is where we do the work. Start by getting our current location and convert the Lat/Long to a map Point, then centre the map on our current location.

    Double lat = location.getLatitude()*1E6;
    Double lng = location.getLongitude()*1E6;
    Point point = new Point(lat.intValue(), lng.intValue());
    mapController.centerMapTo(point, false);

The only thing left to do on our map is draw markers and link them up with lines. To do this you need to create a new class that extends Overlay, and add this using the OverlayController.

    MyLocationOverlay myLocationOverlay = new MyLocationOverlay();
    overlayController.add(myLocationOverlay, true);

The work in the Overlay class is done by overriding the draw method.

    protected class MyLocationOverlay extends Overlay {
      @Override
      public void draw(Canvas canvas, PixelCalculator calculator, boolean
      shadow) {
        ... [ draw things here ] ...
      }
    }

I start by drawing a 'marker' on my current location. There doesn't seem to be support for 'traditional' Google Maps markers but you can achieve the same thing by drawing on the map canvas; I chose to draw small circles as markers. First you need to use the PixelCalculator to convert your Lat/Long points to screen coordinates, then create a Paint object to define the colours and settings for your brush. Then paint your markers.

    int[] screenCoords = new int[2];
    calculator.getPointXY(point, screenCoords);
    RectF oval = new RectF(...);
    Paint paint = new Paint();
    paint.setARGB(200, 255, 0, 0);
    canvas.drawOval(oval, paint);

I add my friends locations the same way as before, iterating over my address book grabbing names and locations. I filter out anyone too far away (say 10km) and draw markers, names (drawText), and joining lines (drawLine) to those nearby.

Let's make a call

Now we know when we're close to our friends, what are we likely to want to do when we're close? Drop in! But we're polite so we'll call them first. Let's change our list item click function to call the friend we've clicked. We can do this by firing a DIAL_ACTION intent.

    Intent i = new Intent();
    i.setAction(DIAL_ACTION);
    i.setData(new ContentURI(numbers.get(position)));
    startActivity(i);

The phone dialer has registered an IntentReceiver filtered on DIAL_ACTION so it will react to this.

Android is an environment where the biggest limitation is your imagination

And that's it.

I've got a list of a dozen or so changes to make it a little more useful and a half dozen ideas for projects that might actually make it into the running for some of that prize money. My conclusion? Android is everything a development kit should be – an environment where the biggest limitation is what you can imagine.

'Computer Science' 카테고리의 다른 글

룩업 테이블  (0) 2010.01.09
EMACS 메뉴얼  (0) 2010.01.03
iPhone Coding Tutorial &#8211; In Application Emailing  (0) 2009.12.25
Introduction to MapKit in iPhone OS 3.0  (0) 2009.12.25
안드로이드 2.0 설치  (0) 2009.12.25

+ Recent posts