みんな大好き! Hello, World
今回のスライドは
この「Hello, World」
  についてだけ
   解説します
% vim hello.py
% chmod u+x hello.py
%
% vim hello.py
% chmod u+x hello.py
% ./hello.py
その前に




  ZSH
unsigned int   引数       タイプ      タイプ

0x241          001 0010 1 (00001) WC_LIST
0xc02          110 0000 2 (00010) WC_SUBLIST
0x083          000 0100 3 (00011) WC_PIPE
0x026          000 0001 6 (00110) WC_SIMPLE
0x000          WC_SIMPLEの引数
0x000          000 0000 0 (00000) WC_END
WC_LIST


              01 0010
                  0: Z_SIMPLE
                  1: Z_END
                  0: Z_DISOWN
                  0: Z_ASYNC
test -f hoge &&   1: Z_SYNC
fuga &            0: Z_TIMED
WC_SUBLIST


            110 0000
                  11: 次のSUBLISTまで
                  0: WC_SUBLIST_SIMPLE
                  0: WC_SUBLIST_NOT
                  0: WC_SUBLIST_COPROC
test -f hoge &&   0: WC_SUBLIST_OR
...               0: WC_SUBLIST_AND
unsigned int   引数       タイプ      タイプ

0x241          001 0010 1 (00001) WC_LIST
0xc02          110 0000 2 (00010) WC_SUBLIST
0x083          000 0100 3 (00011) WC_PIPE
0x026          000 0001 6 (00110) WC_SIMPLE
0x000          WC_SIMPLEの引数
0x000          000 0000 0 (00000) WC_END
WC_PIPE


               000 0110
                     000011: 行番号
                     0: WC_PIPE_MID


tail -f hoge | ...
WC_SIMPLE


               000 0001
                 引数の個数



test -f hoge
WC_SIMPLEの引数


       000 0000
          00000: バッファ位置
          0: 3文字以下?
          0: トークンを含む?

test
3文字以下だと?
たとえばabcが

   00000
   0110 0011 (c)
   0110 0010 (b)
   0110 0001 (a)
   010
   空文字用
さあ、これでPyQ....


  いや、まだまだ
execve(“./hello.py”,...)
     しただけ
do_execve_common()
ファイルを開く
ファイルの先頭128byteを読みこむ
binary handlerの探索
./hello.pyだと
load_script
#!から始まる?
/usr/bin/pythonを読む
/usr/bin/pythonをopen
bprmを新しくして再度binary_handler探索
/usr/bin/python
load_elf
ELF headerを読む
elf interpreterのパス取
 得
elf interpreterとプログ
 ラムを読む
start_thread()
ELF インタプリタ
ライブラリのリンクを行なう
「リンカ・ローダ実践開発テクニック」
Python
/usr/lib/python2.7/site-packages/PyQt4/QtGui.so
initQtGui()
  sipModule = Py_InitModule(sipName_PyQt4_QtGui,
     sip_methods);
C++で書くと…
int main( int argc, char **argv )
{
    QApplication app(argc, argv);
    QPushButton w( "Hello world!");
    app.connect(&w, SIGNAL(clicked()), &w,
     SLOT(close()));
    w.show();
    return app.exec();
}
QPushButton
QPushButton::QPushButton(const QString &text,
                            QWidget *parent)
    : QAbstractButton(*new QPushButtonPrivate, parent)
{
    Q_D(QPushButton);
    setText(text);
    d->init();
}
Q_D
#define Q_D(Class) Class##Private * const d = d_func()


  QpushButtonPrivate * const d = d_func();
  setText(text);
  d->init();
Q_DECLARE_PRIVATE
class QpushButton ...{
Q_DECLARE_PRIVATE(QPushButton)
}


inline const QPushButtonPrivate* d_func() const {
return reinterpret_cast<const QPushButtonPrivate *>
    (qGetPtrHelper(d_ptr));
}
こういうデザインパターンを…
QWidget
    parent == 0なので
    Q_WINDOWになる
    QWidget::create()
     create_sys()
      XCreateWindow()
connect
app.connect(&w, SIGNAL(clicked()), &w,
  SLOT(close()));
connect実装
app.connect(&w, SIGNAL(clicked()), &w,
  SLOT(close()));
→ app.connect(&w, "2clicked()", &w, "1close()");
meta-object
w.show()
w.show(); == w.setVisible(true);
type == Qt::Window?
  d->show_helper()
     show_sys()
         XMapWindow(X11->display, q->internalWinId());
Xとの通信


MapWindow
Xのイベント処理
xorg-server/dix/dispatch.c: Dispatch()
入力イベント処理
イベント待ち
クライアントのイベント処理

クライアントは複数いる
Need Scheduling ...
スケジューリング
   同じ優先度なら
   前回のIDとの差(& 0xff)が大きいも
    の
   スライス: 20msec
   優先度上がる
    40msec以上event来てなかった
    キー入力などが来ている
   優先度下がる
    スライスを使いきる

   一つだけが動いている時は多めに
Rendering.....
window出た
evdev



void
EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
                 int v[MAX_VALUATORS])
{
  EvdevPtr pEvdev = pInfo->private;

    if (pEvdev->rel_queued) {
        xf86PostMotionEventM(pInfo->dev, Relative, pEvdev->vals);
    }
}
Qt signal
conectionListsからシグナル通知先を取得
イベントを投げる

あとはQtのイベントループで処理すれば… !
すばらしいHello, World
 みんなもGentooに
  Hello, world
   してみよう

みんな大好き! Hello, World