http://www.codewrecks.com/blog/index.php/2015/06/23/git-for-windows-getting-invalid-username-or-password-with-wincred/


만약 login이 귀찮아 wincred를 아래처럼 설정해서 썼다면, 비밀번호가 바뀌었을때 대략 난감해진다.

git config --global credential.helper wincred

이 상황에서는 제어판의 "자격 증명 관리자" 를 찾아 들어가 관련 repository와 관련된 것을 지워주고 다시 git 명령을 치면 된다.

저작자 표시
신고

'Open Source > git / svn / bazaar' 카테고리의 다른 글

[GIT] windows에서 invalid username (wincred)  (0) 2016.10.18
commit.template - default commit message  (2) 2012.07.12
resume in github  (2) 2012.02.15
github에 내 사이트 만들기.  (1) 2012.01.17
svn과 proxy  (0) 2010.08.11
Git 사용법(Manual)  (1) 2010.01.10
Posted by 소혼

https://herbsutter.com/2013/05/24/gotw-6a-const-correctness-part-1-3/

https://herbsutter.com/2013/05/24/gotw-6b-const-correctness-part-2/

https://herbsutter.com/2013/05/28/gotw-6b-solution-const-correctness-part-2/


* 번역이 아니라 이해하고 정리한 내용입니다. 따라서 원 글의 의도가 전달되지 않을 수 있으며, 수정 될 수 있습니다.


[ ] https://herbsutter.com/2013/05/24/gotw-6a-const-correctness-part-1-3/


1. shared variable

Shared variable이란 하나 이상의 thread에서 동시에 접근할 수 있는 변수를 말한다.


2. shared variable의 관점에서 const 나 mutable이란?

const member function은 다음 두가지 중 하나를 반드시 만족해야 한다. (절대 공유되지 않는다는 가정이 있지 않는 한)

 - 진짜로 const(truly physically/bitwise const). 다시 말해 객체의 어떤 데이터에도 write하지 않아야 한다.

 - 내부적으로 동기화되어서 (예를 들어 mutex, atomic<> 등으로) 동시에 호출되더라도 문제가 없어야 한다.


비슷하게, 멤버 변수에 mutable 키워드를 쓴다는 것은 그 변수가 쓸 쑤 있지만 논리적으로는 const(writable but logically const) 임을 의미한다.

- 논리적으로 const란 여러 동시성 (const) 연산들로부터 안전하다는 의미이다.

- mutable이 붙어있다는 것은 어떤 const operation이 사실은 write할지 모른다는 뜻이고, 동시성을 갖고 읽고 쓰는데 문제가 없다는 의미이다. 따라서 mutex 나 유사한 동기화 로직 아니면 atomic<>으로 만들어야 한다.


따라서, mutex 와 mutable 을 같이 써야 한다. (또는 atomic<> 과 mutable)


3. c++98과 c++11에서 mutable과 const는 뭐가 다른가?


먼저 그전에...

이 내용을 정리하기 전에, const와 mutable에 대해 헷갈리게 했던 부분은 const_cast를 통해 수정하면 되지 왜 mutable을 써야 하지? 하는 점이었다.

예를 들면 아래 처럼...


#include <vector>

class Tile { ... };

class TileStore {
public:
Tile* getTile() const {
if (empty_tiles_.empty()) {
const_cast<TileStore*>(this)->ReserveMoreTiles();
}
// ...
return //something;
 }
void ReserveMoreTiles() {
// ...
}
private:
std::vector<Tile*> empty_tiles_;
};


먼저 아래 링크을 가져왔다.

http://stackoverflow.com/questions/11457953/const-cast-vs-mutable-any-difference


const_cast는 사실 대상 객체의 const 속성을 제거하는 것이 아니다. 대신 접근 경로(access path)상에 const 속성을 바꿔주는 것이다.

따라서 진짜 const 객체에 대하여 const_cast를 수행하는 것은 Undefined behavior를 야기할 수 있다.


  const int j = 5; // constant object
  const int *p = &j; // `p` is a const access path to `j`

  int *q = const_cast<int *>(p); // `q` is a non-const access path to `j`
  *q = 10; // UNDEFINED BEHAVIOR !!!


그럼 mutable은 뭘까? [1]

 - mutable로 지정된 멤버는 외부에 노출된 클래스의 상태(the externally visible state of the class)에 영향을 받지 않는다.

 - const 클래스의 mutable 멤버는 수정 가능하다.

 - c++은 mutable을 storage-class-specifier로 취급한다.


mutable이 단순히 상수성을 제거한다는 생각을 했는데, 중요한 포인트중 하나는 class가 const여도 된다는 것이다.

즉,

* const_cast는 애초에 다루는 객체가 const이면 안된다.

* mutable은 다루는 객체가 const여도 modifable하다.


위에 적당히 만들어본 Tile & TileStore를 아래처럼 고쳐보았다.


#include <vector>
#include <stdio.h>

class Tile { public: int i; };
class TileStore { public: Tile* getTile() const { if (empty_tiles_.empty()) { const_cast<TileStore*>(this)->ReserveMoreTiles(); }
return empty_tiles_[0]; } void ReserveMoreTiles() {
Tile* tile = new Tile(); tile->i = 10; empty_tiles_.push_back(tile); } private: std::vector<Tile*> empty_tiles_; };
int main() { const TileStore a; Tile* t = a.getTile(); printf("%d\n", t->i); return 0; }

이 동작은 undefined behavior이다. const 객체의 constness를 제거하는 로직이니까.

mutable로 empty_tiles_를 선언해야 맞는 것 같다.


결론적으로 const_cast는 위험하다! (const 객체 안쓴다고 확신할 수 있는가?)


PS. 하지만, QT 5.6으로 컴파일뿐 아니라 실행은 잘 된다. (undefined.... != crash)


3으로 다시 돌아가서....


C++98 single threaded code는 문제 없다. ( 왜 c++98 single threaded code라고 부르는지 모르겠다. )

C++98에서 우리는 const는 논리적인 const(logically const)이며, 물리적인/비트레벨의 const(phisically/bitwise)는 아니다라고 가르쳐왔다.


이제 C++11에서는 const란 read-only 또는 동시성을 고려해서 안전하게 읽을수 있음(safe to read concurrently)을 보장한다.(해야 한다.)

다시 말해 물리적인/비트레벨의 const이거나 내부적으로 동기화되어 어떠한 쓰기 동작도 concurrent한 read access들로부터 동기화되어야 한다.


요약해서,

const correctness 코드를 짜라.

const를 올바르게 사용하는 것은 올바르게 동기화된 코드를 위해 필요하다. 또 const는 그 자체로 "값을 수정하지 않겠다는" 훌륭한 문서이고 컴파일러가 더 나은 코드를 만드는 것을 도와준다.


cosnt 객체나 동작(메소드)에서 멤버를 수정해야 한다면 mutable을 mutex 또는 atomic과 함께 써라.

모든 상용 라이브러리들이 const correct하진 않다.


[ ] https://herbsutter.com/2013/05/28/gotw-6b-solution-const-correctness-part-2/


1. 함수를 선언할때 레퍼런스가 아닌 파라미터의 const는 의미 없다.


void a(const int);
void a(int); // same

void b(const int&);
void b(int&); // different

그러나 inline 함수는 선언과 정의가 같이 있으니까 적는게 의미가 있다.


2. 이항 연산자의 overload시 rhs는 const, lhs는 const가 아닌것이 좋다.

// 잘못된 예제 코드
polygon operator+( polygon& lhs, polygon& rhs ) {
auto ret = lhs;
auto last = rhs.get_num_points();
for( auto i = 0; i < last; ++i ) // concatenate
ret.add_point( rhs.get_point(i) );
return ret;
}

lhs를 ret에 복사하고 있다.

결국 내부에서 한번의 객체 복사가 이뤄져야 하는데, 이 객체가 앞서 호출된 임시객체인 것이 유리할 수 있다.

예를 들어 x = a + b + c;

a + b를 수행하면서 생긴 ret객체를 다시 lhs로 받아서 c와 더하게 된다.


즉, 아래와 같이 하는 것이 비용이 적을 가능성이 있다.

polygon operator+(polygon lhs, const polygon& rhs) {
// ...
return lhs;
}


참조

[1] http://en.cppreference.com/w/cpp/language/cv

저작자 표시
신고

'프로그래밍 언어 > C/C++' 카테고리의 다른 글

[읽은 글] const correctness  (0) 2016.10.18
[C++11] std::function의 성능  (0) 2015.05.29
GCC options  (0) 2013.12.05
[C++11] Range based for loop  (4) 2013.11.13
[C++11] Move semantics  (4) 2013.11.10
[c++11] rvalue reference  (1) 2013.11.07
Posted by 소혼

std::function의 성능이 생각보다 많이 느리다는 것을 알게 되었다.


test.cpp

ryuan@webkit:~$ g++ ./test.cpp --std=c++11 -O3 -DINTERFACE_VERSION
ryuan@webkit:~$ ./a.out
main:96] 8 elapsed
ryuan@webkit:~$ g++ ./test.cpp --std=c++11 -O3 -DINTERFACE_VERSION_NO
ryuan@webkit./a.out
main:96] 437 elapsed


못쓰겠네 -_-;

http://probablydance.com/2013/01/13/a-faster-implementation-of-stdfunction/


[Update]

Modern Effective C++ Item 5 에 따르면

std::function은 단순히 closure와 유사한 것이 아니라 모든 callable object를 담는 것으로...

추가적인 heap 메모리를 사용하는 것 같다.


위 예제를 auto로 바꿔서 테스트해봐야겠다.

저작자 표시
신고

'프로그래밍 언어 > C/C++' 카테고리의 다른 글

[읽은 글] const correctness  (0) 2016.10.18
[C++11] std::function의 성능  (0) 2015.05.29
GCC options  (0) 2013.12.05
[C++11] Range based for loop  (4) 2013.11.13
[C++11] Move semantics  (4) 2013.11.10
[c++11] rvalue reference  (1) 2013.11.07
Posted by 소혼

ewebkit (WebKit/Efl)은 최근 WebKit1 포트를 제거했습니다. 옛날 코드를 사용하지 않는다면, WebKit2만 사용이 가능한 셈입니다.


이 둘의 가장 큰 차이는 이전에 적었던 글에서도 이야기한 것처럼 단일 프로세스를 통해 실행되느냐, 멀티 프로세스 환경에서 실행되는가입니다.

따라서 사용자의 요청(예를 들어 url을 로드해라, resize해라)등은 프로세스간 통신(IPC)을 거쳐 웹 컨텐츠를 담당하는 WebProcess에게 전달됩니다.

그러나 이러한 IPC 메커니즘을 통해 처리하기 어려운 것들이 있습니다. 대표적인 것이 JavaScript binding입니다. JavaScript binding은 native 코드를 javascript interface로 컨텐츠에 추가하여 web page에서 해당 interface를 통해 native code를 수행할 수 있게 하는 방법입니다.

WebKit2에서 이러한 것들을 수행하기 위해서는 WebProcess에서 사용자의 코드들을 수행할 수 있어야 합니다.


이를 위해 Injected Bundle이라는 것을 WebKit2에서는 제공하고 있습니다.

그러나 Injected Bundle은 WebKit2의 인터페이스를 사용하고 있기 때문에, ewebkit은 이를 한단계 감싼 ewk_extension 을 제공합니다.

그림으로 보면 위와 같습니다.

EWebKit2_Extension을 쓰려고 하는 사용자는 EWebKit2_Extension을 이용하여 extension을 만들어야 합니다.

이 때, 반드시 "void ewk_extension_init(Ewk_Extension *extension)" 을 구현하여야 합니다.


또, user application 에서는 ewk_context_new_with_extensions_path()를 사용하여 자신이 작성한 extension 라이브러리의 path를 건네주어야 합니다.


ewebkit은 WebProcess를 실행(fork)할 때, WebProcess가 호출할 injected bundle, 즉 ewebkit_extension_manager의 위치와 사용자 extension의 위치를 같이 넘겨줍니다.

WebProcess는 실행 직후 ewebkit_extension_manager를 로드(dlopen)하고 extension_manager가 extension을 로드하면 extension을 쓸 준비는 끝나게 됩니다.


extension은 이후 WebProcess에 자신이 원하는 타이밍에 WebProcess로부터 콜백들을 받고 적절한 일(javascript binding같은)을 수행할 것이며, message를 이용하여 user application과 서로 통신하게 될 것입니다.


간단한 extension의 예제는 아래에 있습니다.

https://github.com/ewebkit/samples/tree/master/devs/ryuan/extensions


저작자 표시
신고

'Open Source > EFL' 카테고리의 다른 글

[EFL] EWebKit Extension  (0) 2014.09.23
transparent ewebkit  (0) 2014.07.30
Hello ewebkit?  (2) 2014.03.14
WebKit/efl 하면서 쓸 ctags 만들기  (0) 2013.12.17
Elementary Dark theme  (0) 2013.10.17
[TIZEN][EFL] 타이젠 상에서 EFL 예제 실행하기  (9) 2013.08.02
Posted by 소혼

기존 글:

Hello, ewebkit



이번에는 ewk_view에 투명한 배경을 주는 예제를 소개할까 합니다.

기존의 예제(simple.c)를 약간 수정하는 정도의 예제입니다.


먼저 투명한 배경에 대한 설명을 하겠습니다.


일반적으로 웹 페이지는 웹뷰(ewk_view)의 전체 영역에 컨텐츠를 그리게 됩니다.

웹페이지는 body 태그의 배경을 이용하여 컨텐츠의 배경색을 갖게 되는데, 보통 다음과 같이 사용합니다.

### html

<!doctype html>

<!- no background -->

<body>HELLO</body>


### html

<!doctype html>

<body bgcolor="red">Hello, I am red background</body>


### html

<!doctype html>

<head><style>body { background-color: green; } </style></head>

<body>Hello, I am green background</body>


두번째와 세번째는 배경을 갖는 예제인 반면, 첫번째는 배경을 갖지 않는 예제입니다. 그러나 만약 첫번째 예제를 브라우저에서 실행한다면 흰 배경 위에 HELLO라는 글자가 적혀 있는 것을 보게 될 것입니다.


일반적으로 거의 대부분의 브라우저들은 기본 배경을 흰색으로 제공하고 있습니다.

그래서 웹 컨텐츠를 제작하는 대부분의 분들이 배경을 지정하지 않고 있습니다.

(

하지만 만약 흰 배경을 사용하지 않는 브라우저가 나타나면 어쩌실건가요? ㅡ.ㅡ

그리고, 특정 모바일 디스플레이들은 흰색일 때 배터리 소모가 극심합니다.

)


webkit도 기본 배경을 흰색으로 정하고 있지만, 다른 색을 쓰거나, 투명하게 그릴 수 있는 방법을 제공하고 있습니다.

ewebkit에서 관련 API는 ewk_view_bg_color_set 이라는 API가 존재합니다.


### c++

/**
 * Sets the background color and transparency of the view.             
 *
 * @param o view object to change the background color
 * @param r red color component
 * @param g green color component                                          
 * @param b blue color component     
 * @param a transparency             
 */
EAPI void ewk_view_bg_color_set(Evas_Object *o, int r, int g, int b, int a);

각각의 color component들은 0 부터 255 사이의 숫자여야 합니다.


일반적으로 EFL에서는 evas_object_color_set이라는 API를 이용하여 evas object의 색을 지정했지만,

ewebkit에서는 alpha를 제외하곤 evas_object_color_set의 다른 인자들을 사실상 무시합니다.

이유는, evas_object_color_set의 alpha가 전체 컨텐츠의 opacity를 다루는 반면, ewebkit은 배경만의 opacity를 다루어야 하는 요구사항이 있기 때문입니다.

즉, evas_object_color_set은 evas_object 전체의 색을 조절하는 API로 ewebkit에서는 contents의 색은 contents가 지정해야 하기 때문에 RGB값은 무시됩니다. (현재)


ewk_view_bg_color_set 을 사용하는 예제는 아래와 같습니다.

https://github.com/ewebkit/samples/blob/master/devs/ryuan/transparent.c

### c++

// gcc transparent.cpp `pkg-config --cflags --libs elementary ewebkit2
#include <Elementary.h>
#include <EWebKit2.h>

void on_done(void *userData, Evas_Object *webView, void *eventInfo)
{
   elm_exit();
}

EAPI_MAIN int
elm_main(int argc, char *argv[])
{
   ewk_init();

   Evas_Object* win;
   win = elm_win_add(NULL, "sample", ELM_WIN_BASIC);
   elm_win_title_set(win, "sample");
   evas_object_smart_callback_add(win, "delete,request", on_done, NULL);
   elm_win_autodel_set(win, EINA_TRUE);

   Evas_Object* bg = elm_bg_add(win);
   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   elm_bg_color_set(bg, 0, 0, 255);
   elm_win_resize_object_add(win, bg);
   evas_object_show(bg);

   Evas_Object* ewk = ewk_view_add(evas_object_evas_get(win));
   ewk_view_html_string_load(ewk, "<!doctype html><body>HELLO</body>", NULL, NULL);
   ewk_view_bg_color_set(ewk, 0, 0, 0, 0);

   evas_object_resize(ewk, 400, 400);
   evas_object_move(ewk, 0, 0);
   evas_object_show(ewk);

   evas_object_resize(win, 400, 400);
   evas_object_show(win);

   elm_run();

   ewk_shutdown();
}
ELM_MAIN()

배경 속성이 없는 web contents를 위해 url 대신 ewk_view_html_string_load를 이용했습니다.

그리고 ewk_view_bg_color_set 을 통해 ewk_view의 배경을 투명하게 만든 예제입니다.


위에서 elm_bg의 색을 blue로 했기 때문에 파란색 배경 위에 HELLO라는 글자가 적혀있어야 합니다.

만약 검은색으로 나온다면, ewebkit을 최신으로 빌드해보시기 바랍니다.

(최근 수정 :https://bugs.webkit.org/show_bug.cgi?id=135333)


추신. 현재 ewk_view_bg_color_set과 EFL 관련 버그가 하나 더 있는 것 같습니다.

만약 ewk_view_bg_color_set의 RGB요소에 값을 주고 alpha를 준 경우, elm_bg의 색과 blend되고 있습니다.

만약 투명한 웹뷰가 필요한 경우라면 RGB요소를 모두 0으로 주시기 바랍니다.

저작자 표시
신고

'Open Source > EFL' 카테고리의 다른 글

[EFL] EWebKit Extension  (0) 2014.09.23
transparent ewebkit  (0) 2014.07.30
Hello ewebkit?  (2) 2014.03.14
WebKit/efl 하면서 쓸 ctags 만들기  (0) 2013.12.17
Elementary Dark theme  (0) 2013.10.17
[TIZEN][EFL] 타이젠 상에서 EFL 예제 실행하기  (9) 2013.08.02
Posted by 소혼

일반적으로 픽셀(pixel)은 아래처럼 설명할 수 있습니다.[1][2]

"In digital imaging, a pixel, pel,or picture element is a physical point in a raster image, or the smallest addressable element in an all points addressable display device; so it is the smallest controllable element of a picture represented on the screen." (출처 : wikipedia)


흔히 TV/모니터는 얼마나 많은 픽셀을 표현하는지를 (display) resolution이라고 부르며 (물리적인) 픽셀로 처리합니다.[3]

( 해상도 관련 글 )

그래서 그동안 프로그래밍을 하는 과정에서 픽셀이라는 개념은 물리적인 스크린의 한 점과 같다고 생각해 왔습니다.


최근 모바일 (그리고 모바일 웹)에서 이러한 픽셀의 개념에 큰 혼란이 생겨 개인적으로 조사한 내용을 적으려고 합니다.


아이폰의 등장

2007년 초 아이폰과 이후 안드로이드의 등장으로 모바일 디바이스는 스마트폰(그전에도 존재했지만)의 세상이 되었습니다.

이들 스마트폰이 등장하면서 모바일 브라우저는 기존 웹 페이지를 '거의' 문제 없이 모바일에서 렌더링할 수 있게 되었습니다.


레티나 디스플레이의 등장

2010년 애플은 아이폰4에 레티나 디스플레이라는 화면 구성을 가져옵니다. 이는 기존의 아이폰 3에 비해 사실상 두배의 해상도를 갖는 디스플레이(640 x 960)입니다.

(사실 레티나 디스플레이에서 중요한 것은 DPI 로 특정 시야거리에서 기존의 160 ppi 의 두배인 326 ppi 를 만족한다는 의미로 레티나라고 불렀던 것으로 압니다.)

여기에서 한가지 문제점은 기존의 앱/웹페이지들이 320 x 480에 최적화 되어 있다는 것이었습니다.

이를 위해 애플은 웹의 경우 device pixel ratio 라는 요소를 가져왔습니다.

즉, device의 width는 320으로 놓고 대신 pixel ratio의 값을 2로 설정하도록 한 것입니다.

여기서 새로운 픽셀의 정의가 생겨나고 말았습니다.

웹페이지는 contents가 320픽셀이라고 생각하지만, 실제 물리적인 픽셀은 640픽셀인 것입니다.

다시 말해 우리가 width=100 px 의 DIV태그를 만들면 화면상에는 200px의 박스가 그려지게 됩니다.


안드로이드의 따라하기.

후발주자인 안드로이드는 어쩔수 없이 애플이 만들어놓은 컨텐츠를 잘 그리기 위해서 아이폰의 많은 부분을 그대로 차용하게 됩니다.

그래서 레티나급 디바이스에 대해 유사하게 2.0의 device pixel ratio를 사용하게 됩니다.

문제는 안드로이드는 정말 많은 디바이스가 존재하고 각 디바이스들이 전부 ppi가 달랐습니다.

target-density라는 개념을 통해 device 별로 테이블을 만들고 했지만, 문제는 간단하지 않았던 것 같습니다.

device pixel ratio는 아이폰의 의미와 약간 다르게 device의 ppi를 고려하여 1.5 2.0 3.0등 다양한 값을 갖게 되었습니다.

여기서, 이 값이 실제 1.0 일 때의 ppi에 정확히 비례하지 않을 뿐 아니라, 실제 단말의 픽셀과도 정확히 일치하지 않게 됩니다.

즉, 1.5 의 단말의 픽셀이 320 x 1.5 = 480 px 이 아닌 단말들도 많아지게 됩니다.


사실 w3c에서는...

사실 웹 표준인 w3c에서는픽셀에 대한 정의를 "Reference pixel"이라고 정의하고 있었습니다. [4]


Showing that pixels must become larger if the viewing distance increases


The reference pixel is the visual angle of one pixel on a device with a pixel density of 96dpi and a distance from the reader of an arm’s length. For a nominal arm’s length of 28 inches, the visual angle is therefore about 0.0213 degrees. For reading at arm’s length, 1px thus corresponds to about 0.26 mm (1/96 inch).


애초에 물리 픽셀 과 논리 픽셀을 구분해둔 셈입니다.


일반적으로 모니터는 팔길이 정도의 시야거리(viewing distance)를 갖고 있고 96 dpi 였습니다. 웹 표준을 만들 때 이미 시야거리의 변화와 dpi의 변화를 고려하여 가상의 픽셀인 reference pixel을 정의하고 있었고 웹은 이 값에 기반하여 cm, inch등으로 픽셀값을 변환할 수 있었습니다.

그러나 모바일 벤더들은 96dpi를 바꾸지 않았습니다.(여러가지 문제가 있었을 거라고 생각됩니다.)

따라서 160dpi나 326dpi인 아이폰에서도 1 픽셀을 인치로 변환하면 1/96이 나오게 된 것입니다.


아이폰과 같은 모바일의 시야거리는 대략 10 inch (25cm) 라고 생각할 수 있습니다.

대충 계산하면 동일한 시야각을 얻으려면 픽셀은 0.1 mm 여야 할듯 합니다.

0.26 : 71 = x : 25


다시 말해 모니터와 같은 reference pixel(같은 시야각을 같는 픽셀)을 얻으려면 대략 243 dpi가 나와야 합니다.

하지만 현재 모바일은 160 dpi를 de-factor처럼 사용하고 있는 셈입니다.

심지어, 그 값도 단말에 따라 약간씩 다릅니다.


결론적으로

1. 웹에서 현재 있는 cm , inch 등은 printer를 media type을 위해서 사용해야 합니다.

     px과 cm간의 변환은 사실상 의미를 잃어버렸습니다.

2. px 정보(screen.width window.clientWidth) 를 이용하여 디바이스의 크기를 알아내는 것은 사실상 불가능해졌습니다.

     현재의 웹은 디바이스의 크기를 알 방법을 제공하지 않습니다.

     당연히 디바이스의 크기를 구분할 수 있는 올바른 방법은 존재하지 않고 미디어쿼리나 user agent를 통해 이미 알고 있는 디바이스만을 고려할 수 있게 되었습니다.


참고 :

[1] (한글) http://ko.wikipedia.org/wiki/%ED%99%94%EC%86%8C

[2] (영문) http://en.wikipedia.org/wiki/Pixel

[3] http://en.wikipedia.org/wiki/Display_resolution

[4] http://dev.w3.org/csswg/css-values/

http://ko.wikipedia.org/wiki/%EB%A0%88%ED%8B%B0%EB%82%98_%EB%94%94%EC%8A%A4%ED%94%8C%EB%A0%88%EC%9D%B4

http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html

http://alistapart.com/article/a-pixel-identity-crisis/


저작자 표시
신고
Posted by 소혼



저작자 표시
신고

'Life is... > Photo-Diary' 카테고리의 다른 글

2014 webkit meeting  (0) 2014.04.16
천사 가영.  (1) 2012.10.07
바다 손  (0) 2011.05.24
에버랜드 나무  (0) 2010.06.23
Posted by 소혼


Tizen Wearable SDK beta 1.0 이 릴리즈 되었습니다.

( http://developer.samsung.com/samsung-mobile-sdk/ )


아래는 기본으로 설치되어 있는 예제들 사진입니다.


에뮬레이터와 Analog watch 화면


카메라 앱과 에뮬레이터 콘트롤 패널




저작자 표시
신고

'Open Source' 카테고리의 다른 글

Tizen Wearable SDK 예제 사진  (0) 2014.03.18
Qt (framework)설치 on Ubuntu(우분투)  (0) 2011.04.12
[benchmark] jsgamebench  (0) 2011.03.22
[번역] bison(바이슨?) license  (0) 2011.01.22
bada SDK 설치하기  (2) 2010.08.20
FreeNode IRC 접속  (0) 2009.12.10
Posted by 소혼
TAG Tizen
2014.03.14 08:44

ewebkit은 WebKit 엔진 기반에 EFL 라이브러리를 사용하여 UI를 표현하는 라이브러리입니다.

(WebKit/EFL 이라고도 부르는데,  저는 so 파일 이름에 따라 ewebkit이라고 부르고 있습니다.)


물론,  Elementary의 elm_web이 ewebkit 에서 사용하는 ewk_view의 간단한 wrapper 클래스이지만 아직 문제가 많은 상태이기 때문에(1.9) ewebkit을 직접 쓰는 방법을 권장하고 있습니다. (또 타이젠(~2.2) 에서는 elm_web을 사용하실 수 없습니다.)

이 글에서는 elm_web이 아닌 ewk_view를 사용해서 간단한 페이지를 만드는 법을 공유하려고 합니다.


ewebkit 라이브러리는 현재 두 종류가 있습니다.

ewebkit : WebKit1/EFL 포트에 기반하는 라이브러리

ewebkit2 : WebKit2/EFL 포트에 기반하는 라이브러리


둘의 가장 큰 차이는 간단히 설명드리면 웹페이지를 렌더링하는 코어영역을 같은 프로세스에서 처리하느냐(ewebkit), 다른 프로세스에서 처리하느냐(ewebkit2) 입니다.

대부분의 인터페이스는 유사하지만, 이런 프로세스 모델의 차이에서 몇몇 인터페이스에는 차이가 있습니다.


참고로 타이젠과 같은 경우 1.0에서는 ewebkit을 사용하였고, 2.0부터는 ewebkit2를 사용하고 있습니다.

(현재 ewebkit은 webkit.org에서 제거되어 ewebkit2만 남았습니다.)


ewebkit을 사용한 코드들은 elm_web (http://git.enlightenment.org/core/elementary.git/tree/src/lib/elm_web.c) 이나 WebKit 프로젝트 내의 http://trac.webkit.org/browser/trunk/Tools/EWebLauncher/main.c 가있습니다.

ewebkit2를 사용한 코드들은 elm_web2(http://git.enlightenment.org/core/elementary.git/tree/src/lib/elm_web2.c),  또는 WebKit 프로젝트 내의 http://trac.webkit.org/browser/trunk/Tools/MiniBrowser/efl/main.c 가 있습니다.


참고삼아 보시면 될 듯 하고, 이 글에서는 ewebkit2 의 코드를 MiniBrowser 기반으로 설명을 드리려고 합니다.

(http://trac.webkit.org/browser/trunk/Tools/MiniBrowser/efl/main.c 정도의 설명입니다.)


혹시 EFL 에 대해서 잘 모르신다면, 이 글을 읽기에 부담스러우실 수 있습니다.

(과감히 뒤로가기를 누르셔도 됩니다.)


(

혹, EFL에 관심이 있으시면 먼저 아래 글을 보시는 것을 추천드립니다.

https://events.linuxfoundation.org/images/stories/pdf/lfcs2012_raster.pdf

)


1. 생성 / 소멸

다른 EFL 라이브러리들처럼 ewebkit/ewebkit2도 전역의  _init 과  _shutdown 을 가지고 있습니다.


### c++

int main ()

{

    ewk_init();

    ...

    ewk_shutdown();

    return 0;

}

반드시 사용하기 전에 호출해주셔야 합니다.

가능하면 main 시작하자마자 ewk_init을 호출하고, loop가 끝난 후 ewk_shutdown을 호출해주시는 것이 좋습니다.


다음으로,ewk_view 객체를 만들어야 합니다.

ewk_view를 만드는 방법은 여러가지가 있습니다. 하나씩 살펴보도록 하겠습니다.


1) ewk_view_add(Evas *e)

ewk_view_add 는 ewk_view를 만드는 가장 쉬운 방법입니다.

간단한 페이지를 로드하는 데는 적합하지만, alert/prompt/confirm이라던가 새창을 열거나 그 밖에 UI의 도움을 받아야 하는 많은 것들을 할 수 없습니다.

또, ewebkit에서는 관계없으나 ewebkit2에서는 매 evas object가 별도의 WebProcess를 생성하여 동작하게 됩니다.


### c++

Evas_Object *o = ewk_view_add(e);

ewk_view_url_set(o, "http://bunhere.tistory.com");


2) ewk_view_add_with_context(Evas *e, Ewk_Context *context)

ewebkit에서는 없는 함수입니다.

ewebkit2에서는 web context 라는 것이 있어서 하나의 web context는 하나의 WebProcess를 생성하게 합니다. 만약 이미 생성한 web context 안에 웹뷰를 만들려고 하면 이 함수를 사용해서 생성하면 됩니다.


### c++

// o 와 같은 context(web process)에서 동작하는 ewk_view를 생성

Evas_Object *o2 = ewk_view_add_with_context(e, ewk_view_context_get(o));


3) ewk_view_smart_add(Evas *e, Evas_Smart *smart, Ewk_Context *context, Ewk_Page_Group *group)

해당 API는 ewebkit에는 없습니다.(유사한 방법이 있으나 별도의 API 로 존재하지 않습니다.)


이 API 를 쓰면 ewk_view가 할 수 있는 일을 모두 할 수 있습니다.

물론 그만큼 사용하기 어렵다는 문제도 있습니다.


먼저, 인자들을 하나씩 살펴보도록 하겠습니다.

Evas *e

현재 생성하는 ewk_view의 기반이 될 canvas입니다.


Evas_Smart *smart

ewk_view는 여러 Evas_Object들 중 smart object로 만들어졌습니다.

Smart Object를 만드는 것에 대한 자세한 내용은 아래 글을 참고하시면 좋을 것 같습니다.

http://docs.enlightenment.org/stable/efl/Example_Evas_Smart_Objects.html


일반적으로 smart object를 만들때는 smart class를 만들어서 evas_object_smart_add를 호출하면 되지만, ewk_view는 추가로 처리해야 하는 인자들이 있어서 ewk_view_smart_add를 대신 사용합니다.

ewk_view_smart_add는 내부적으로 evas_object_smart_add의 일을 수행하게 됩니다.

(ewebkit은 evas_object_smart_add를 사용합니다.)

Evas_Smart를 만드는 법은 복잡하기 때문에 아래에서 다시 설명하겠습니다.


Ewk_Context *context

여러 ewk_view는 하나의 context를 가질 수도 있고, 여러개의 context를 가질 수도 있습니다.

하나의 context에 기반한 ewk_view들은 많은 것을 공유하게 됩니다.

특히 하나의 프로세스에서 수행되게 될 것입니다.

context를 구하려면 기존의 ewk_view 를 이용하여 ewk_view_context_get(o)을 하거나, ewk_context_default_get()을 이용하여 default context를 생성하면 됩니다.


Ewk_Page_Group *group

page group을 이해하는 쉬운 예제는 자바스크립트로 실행한 새창입니다. 자바스크립트로 새창을 열면 해당 페이지와 새로 열린 페이지는 opener / child 관계를 갖게 됩니다. 이 두 페이지는 같은 세팅을 가져야 합니다. 세션도 공유할 것이고요.

이렇게 같은 설정을 가져야 하고 정보들을 공유해야 한다면 같은 page group으로 묶어야 합니다.

page group을 얻는 방법은 기존의 ewk_view를 이용하여 ewk_view_page_group(o)을 호출하거나 ewk_page_group_create(group_name) 을 호출하여 특정 그룹을 생성하면 됩니다. group_name이 null이면 임의의 그룹을 생성하게 됩니다.


Evas_Smart 만들기

Evas_Smart를 만들려면 smart class를 하나 만들어야 합니다.

특히 ewk_view를 위한 smart class는 Evas_Smart_Class 를 확장한 Ewk_View_Smart_Class입니다.

사용자는 Ewk_View_Smart_Class를 확장하거나, Ewk_View_Smart_Class를 고쳐서 쓸 수 있습니다.

확장을 해서 쓸 경우, 기본 구현을 오버라이드하여 이용하기 좋다는 장점이 있습니다만, 대부분의 경우에는 기본 구현이 없습니다.(마우스/터치 이벤트 제외)


이 글에서는 일단 Ewk_View_Smart_Class를 고쳐서 쓰려고 합니다.

###  c++

static Ewk_View_Smart_Class *miniBrowserViewSmartClass()                                                                                                                 
{
    static Ewk_View_Smart_Class ewkViewClass = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("MiniBrowser_View");
    return &ewkViewClass;
}

MiniBrowser에서 발췌한 코드로 Ewk_View_Smart_Class 객체를 하나 만들어서 MiniBrowser_View라는 이름으로 초기화했습니다.

이 때, 값들은 모두 NULL로 초기화 될 것입니다.

ewk_view가 제공하는 메소드들로 재정의하기 위해서 ewk_view_smart_class_set을 호출해 주어야 합니다.

사실 ewk_view는 재정의할 메소드들이 별로 없습니다만 이 함수는 반드시 호출되어야 합니다. 가장 중요한 Evas_Smart_Class의 메소드들이 연결될 것입니다.

### c++

    if (!ewk_init())
        return EXIT_FAILURE;

    ewk_view_smart_class_set(miniBrowserViewSmartClass());


이제 어플리케이션에서 필요로 하는 기능들에 대해 추가로 수정을 하시면 됩니다.

### c++

    Ewk_View_Smart_Class *ewkViewClass = miniBrowserViewSmartClass();                                                                                                    
    ewkViewClass->run_javascript_alert = on_javascript_alert;
    ewkViewClass->run_javascript_confirm = on_javascript_confirm;
    ewkViewClass->run_javascript_prompt = on_javascript_prompt;
    ewkViewClass->window_geometry_get = on_window_geometry_get;
    ewkViewClass->window_geometry_set = on_window_geometry_set;
    ewkViewClass->fullscreen_enter = on_fullscreen_enter;
    ewkViewClass->fullscreen_exit = on_fullscreen_exit;
    ewkViewClass->window_create = on_window_create;
    ewkViewClass->window_close = on_window_close;
    ewkViewClass->popup_menu_show = on_popup_menu_show;
    ewkViewClass->popup_menu_hide = on_popup_menu_hide;
    ewkViewClass->context_menu_show = on_context_menu_show;
    ewkViewClass->context_menu_hide = on_context_menu_hide;
    ewkViewClass->input_picker_color_request = on_color_picker_request;
    ewkViewClass->input_picker_color_dismiss = on_color_picker_dismiss;

앞서 말씀 드린 것과 같이 마우스 이벤트와 같은 몇몇 이벤트를 제외하면 ewkViewClass가 추가한 메소드들은 특수한 구현들을 갖고 있지 않습니다.


각각의 메소드들이 어떤 인자들과 반환값을 가져야 하는지는 http://trac.webkit.org/browser/trunk/Source/WebKit2/UIProcess/API/efl/ewk_view.h 를 참고하셔야 합니다.

몇몇 메소드들은 아래에서 좀 더 설명하도록 하겠습니다.


이렇게 smart class가 준비되었다면 Evas_Smart를 만들면 됩니다.

### c++

Evas_Smart *smart = evas_smart_class_new(&ewkViewClass->sc);

sc는 Evas_Smart_Class를 가르키는 주소입니다.


아래는 MiniBrowser에서 ewk_view_smart_add를 호출하는 일부 코드입니다..

### c++

    Evas *evas = evas_object_evas_get(window->elm_window);
    Evas_Smart *smart = evas_smart_class_new(&ewkViewClass->sc);
    Ewk_Context *context = opener ? ewk_view_context_get(opener) : ewk_context_default_get();
    Ewk_Page_Group *pageGroup = opener ? ewk_view_page_group_get(opener) : ewk_page_group_create("");
    window->ewk_view = ewk_view_smart_add(evas, smart, context, pageGroup);


생성과 달리 소멸은 간단히 evas_object_del을 호출해주면 됩니다.


2. Load contents

ewebkit에서 contents를 읽는 방법은 두가지가 있습니다.
가장 기본적인 방법인 url을 읽는 방법과, html string을 읽는 방법입니다.


url을 읽는 API는 다음과 같습니다.

### c++

ewk_view_url_set(view, "http://bunhere.tistory.com");

그 다음은 알아서 로딩이 된 후, 화면에 그려지게 됩니다.


html string을 직접 읽는 방법도 크게 어렵지는 않습니다.

### c++

ewk_view_html_string_load(view, "<!doctype html><body>hello</body>", base_uri, unreachable_uri);

img나 기타 리소스들이 상대 경로로 놓여질 때 읽어올 base_uri, 에러가 났을때 알려줄 unreachable_uri가 추가된 것을 제외하면 특별한 것이 없습니다. 그리고 이 값들은 NULL로 넘겨도 상관없습니다.


간단한 예제


여기까지 이야기한 것들을 바탕으로 가장 간단한 ewebkit 기반의 웹브라우저를 만들어보겠습니다.

https://github.com/ewebkit/samples/blob/master/devs/ryuan/simple.c

### c++

// gcc simplebutton.cpp `pkg-config --cflags --libs elementary ewebkit2`           
#include <Elementary.h>                                                            
#include <EWebKit2.h>                                                              
                                                                                   
void on_done(void *userData, Evas_Object *webView, void *eventInfo)
{
   elm_exit();
}

EAPI_MAIN int
elm_main(int argc, char *argv[])
{
   ewk_init();

   Evas_Object* win;
   win = elm_win_add(NULL, "sample", ELM_WIN_BASIC);
   elm_win_title_set(win, "sample");
   evas_object_smart_callback_add(win, "delete,request", on_done, NULL);
   elm_win_autodel_set(win, EINA_TRUE);

   Evas_Object* bg = elm_bg_add(win);
   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   elm_bg_color_set(bg, 0, 0, 255);
   elm_win_resize_object_add(win, bg);
   evas_object_show(bg);

   Evas_Object* ewk = ewk_view_add(evas_object_evas_get(win));
   ewk_view_url_set(ewk, "http://bunhere.tistory.com");

   evas_object_resize(ewk, 400, 400);
   evas_object_move(ewk, 0, 0);
   evas_object_show(ewk);

   evas_object_resize(win, 400, 400);
   evas_object_show(win);

   elm_run();

   ewk_shutdown();                                                                                                                                                      
}                                                                                  
ELM_MAIN()


실행 결과입니다.



저작자 표시
신고

'Open Source > EFL' 카테고리의 다른 글

[EFL] EWebKit Extension  (0) 2014.09.23
transparent ewebkit  (0) 2014.07.30
Hello ewebkit?  (2) 2014.03.14
WebKit/efl 하면서 쓸 ctags 만들기  (0) 2013.12.17
Elementary Dark theme  (0) 2013.10.17
[TIZEN][EFL] 타이젠 상에서 EFL 예제 실행하기  (9) 2013.08.02
Posted by 소혼
TAG EFL, Webkit

ctags -R --exclude=.git --exclude=Examples --exclude=LayoutTests --exclude=ManualTests --exclude=WebKitLibraries --exclude=build --exclude=PerformanceTests  --exclude=Tools --exclude=WebKit.xcworkspace --exclude=layout-test-results  --exclude=WebKitBuild  --exclude=Websites --exclude=Source/*/win --exclude=Source/*/mac --exclude=Source/*/wince --exclude=Source/*/blackberry --exclude=Source/*/mac --exclude=Source/WebKit/--exclude=*.html --exclude=*.js --exclude=*.pl --exclude=*.php .

저작자 표시
신고

'Open Source > EFL' 카테고리의 다른 글

transparent ewebkit  (0) 2014.07.30
Hello ewebkit?  (2) 2014.03.14
WebKit/efl 하면서 쓸 ctags 만들기  (0) 2013.12.17
Elementary Dark theme  (0) 2013.10.17
[TIZEN][EFL] 타이젠 상에서 EFL 예제 실행하기  (9) 2013.08.02
[TIZEN] 2.2 Emulator 실행하기  (0) 2013.08.01
Posted by 소혼

티스토리 툴바