February 02, 2006

ToyWM 的建構紀錄

之前的 blog [ToyWM : 體驗 ICCCM 與 EWMH 規格的練習],提到我正在開發的 ToyWM,這過程的確讓我又對 X11 有了更深入的認知。如果不看一般 window manager 的功能性,ToyWM 在顯示處理做了些變化。首先,使用了 Keith Packard 設計的 [XRender extension],目前 ToyWM 的 icon / window border 以及 anti-aliasing font 都透過 XRender 來作顯示,至於原本規劃的 Cairo-based rendering,可能會放棄,我沒有打算作太複雜的繪圖處理。目前的執行畫面如下:

前面提到的 XRender extension 還做了陰影的處理,這是一個簡單內建 composite manager 的展示,並且因為與 WM 整合,所以效能還是可以接受的範圍。圖中執行的應用程式就是 PCMan 最近開發的 [PCMan File Manager],比較有趣的地方在左上角,小小的 "ToyWM" 字樣,這是透過 SHAPE extension 與 SERVER_OVERLAY_VISUALS 來實現 transparent visual,這部份的實做程式片段如下:
    struct overlay_data
    {
      CARD32 visual_id;
      CARD32 transparency;  /**< 
          0: none;
          1: pixel; 
          2: mask (?) */
      CARD32 value;         /**< the transparent pixel */
      CARD32 layer;         /**< 
          -1: underlay; 
          0: normal; 
          1: popup; 
          2: overlay */
    };
    
    static int
    get_overlay_prop (
        Screen *screen, 
        struct overlay_data **data_ret)
    {
      int result;
      Atom actual_type;
      int actual_format;
      unsigned long nitems, bytes_after;
      struct overlay_data *data = 0;
      Display *dpy = DisplayOfScreen(screen);
      Window window = RootWindowOfScreen(screen);
      Atom XA_SERVER_OVERLAY_VISUALS =
          XInternAtom (dpy, 
              "SERVER_OVERLAY_VISUALS", False);
    
      *data_ret = 0;
      result = XGetWindowProperty (dpy, 
          window, 
          XA_SERVER_OVERLAY_VISUALS,
          0, (65536 / sizeof (long)), False,
          XA_SERVER_OVERLAY_VISUALS,
          &actual_type, &actual_format,
          &nitems, &bytes_after,
          (unsigned char **) &data);
      if (result != Success ||
          actual_type != XA_SERVER_OVERLAY_VISUALS ||
          actual_format != 32 ||
          nitems < 1) {
          if (data) {
            XFree(data);
           }
          return 0;
      }
      else {
          *data_ret = data;
          return nitems / (sizeof(*data) / sizeof(CARD32));
        }
    }
    
    Visual *
    get_overlay_visual (
        Screen *screen, 
        unsigned long *transparent_pixel_ret)
    {
      struct overlay_data *data = 0;
      int n_visuals = get_overlay_prop (screen, &data);
      Visual *visual = 0;
      int depth = 0;
      unsigned long pixel = 0;
      unsigned int layer = 0;
      int i;
    
      if (data)
        for (i = 0; i < n_visuals; i++)
     
          /* Only accept the ones that 
              have a transparent pixel. */
          if (data[i].transparency == 1) {
              XVisualInfo vi_in, *vi_out;
              int out_count;
              vi_in.visualid = data[i].visual_id;
              vi_out = XGetVisualInfo(
                  DisplayOfScreen(screen), 
                  VisualIDMask,
                  &vi_in, &out_count);
              if (vi_out) {
                  /* Prefer the one at the topmost layer; 
                     after that, prefer the one with the 
                     greatest depth (most colors.) */
    
                  if (layer < data[i].layer ||
                      (layer == data[i].layer &&
                       depth < vi_out[0].depth)) {
                      visual = vi_out[0].visual;
                      depth  = vi_out[0].depth;
                      layer  = data[i].layer;
                      pixel  = data[i].value;
                  }
                  XFree(vi_out);
              }
          }
    
      if (data) {
        XFree(data);
      }
      if (visual && transparent_pixel_ret)
        *transparent_pixel_ret = pixel;
      return visual;
    }
還有,XShapeCombineMask 這個 API 的使用也要小心。
由 jserv 發表於 February 2, 2006 05:32 PM
迴響

想請教一下,您寫 blog 時,通常都用甚麼工具來將你的
source code 轉成 html 的?

Yukuan 發表於 February 4, 2006 05:39 PM

To Yukuan,
程式碼排版可使用 http://rafb.net/
張貼後,會產生 HTML 輸出,可以選擇是否要行號。

jserv 發表於 February 4, 2006 05:51 PM

謝謝!
我最後決定使用 Dev-C++ 的 Export to html 功能。

Yukuan 發表於 March 5, 2006 01:37 AM