Chinaunix首页 | 论坛 | 博客
  • 博客访问: 678411
  • 博文数量: 156
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 1201
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-05 20:08
文章分类

全部博文(156)

文章存档

2010年(13)

2008年(39)

2007年(104)

我的朋友

分类: C/C++

2007-07-22 22:02:02

这个是conky.c中的main_loop()的函数的内容

static void main_loop()//主要的循环,^_^

{
#ifdef SIGNAL_BLOCKING
//阻塞信号

    sigset_t newmask, oldmask;

    sigemptyset(&newmask);
    sigaddset(&newmask,SIGINT);
    sigaddset(&newmask,SIGTERM);
    sigaddset(&newmask,SIGUSR1);
#endif

#ifdef X11
    Region region = XCreateRegion();
//create a new empty region

#ifdef HAVE_XDAMAGE
    int event_base, error_base;
    if (!XDamageQueryExtension (display, &event_base, &error_base)) {
        ERR("Xdamage extension unavailable");
    }
    Damage damage = XDamageCreate(display, window.window, XDamageReportNonEmpty);
    XserverRegion region2 = XFixesCreateRegionFromWindow(display, window.window, 0);
    XserverRegion part = XFixesCreateRegionFromWindow(display, window.window, 0);
#endif /* HAVE_XDAMAGE */
#endif /* X11 */

    info.looped = 0;
    while (total_run_times == 0 || info.looped < total_run_times) {
        info.looped++;

#ifdef SIGNAL_BLOCKING
        /* block signals. we will inspect for pending signals later */
//首先阻塞信号,准备好以后再打开

        if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
            CRIT_ERR("unable to sigprocmask()");
#endif

#ifdef X11
        XFlush(display);
// flushes the output buffer


        /* wait for X event or timeout */

        if (!XPending(display)) {
//display Specifies the connection to the X server

            fd_set fdsr;
            struct timeval tv;
            int s;
            double t =
             update_interval - (get_time() -
                     last_update_time);

            if (t < 0)
                t = 0;

            tv.tv_sec = (long) t;
            tv.tv_usec = (long) (t * 1000000) % 1000000;
            FD_ZERO(&fdsr);
            FD_SET(ConnectionNumber(display), &fdsr);


            s = select(ConnectionNumber(display) + 1, &fdsr, 0,
                 0, &tv);
#else
            usleep(update_interval*1000000); /* FIXME just sleep for the interval time if no X11 */
#endif /* X11 */
#ifdef X11
            if (s == -1) {
                if (errno != EINTR)
                    ERR("can't select(): %s",
                     strerror(errno));
            } else {
                /* timeout */
                if (s == 0)
#endif /* X11 */
                    update_text();
//更新显示的文本

#ifdef X11
            }
        }
        
        if (need_to_update) {
#ifdef OWN_WINDOW
            int wx = window.x, wy = window.y;
#endif

            need_to_update = 0;
            selected_font = 0;
            update_text_area();
//更新文本显示区

#ifdef OWN_WINDOW
            if (own_window) {
                /* resize window if it isn't right size */
                if (!fixed_size &&
                 (text_width + border_margin * 2 + 1 !=
                 window.width
                 || text_height + border_margin * 2 + 1 !=
                 window.height)) {
                    window.width =
                     text_width +
                     border_margin * 2 + 1;
                    window.height =
                     text_height +
                     border_margin * 2 + 1;
                    XResizeWindow(display,
                         window.window,
                         window.width,
                         window.height);
            if (own_window) {
                set_transparent_background(window.window);
            }
                 }

                /* move window if it isn't in right position */
                if (!fixed_pos
                 && (window.x != wx
                    || window.y != wy)) {
                    XMoveWindow(display, window.window,
                         window.x, window.y);
                }
            }
#endif

            clear_text(1);

#ifdef HAVE_XDBE
            if (use_xdbe) {
                XRectangle r;
                r.x = text_start_x - border_margin;
                r.y = text_start_y - border_margin;
                r.width = text_width + border_margin * 2;
                r.height = text_height + border_margin * 2;
                XUnionRectWithRegion(&r, region, region);
            }
#endif
        }

        /* handle X events */
//支持X的事件


        while (XPending(display)) {
            XEvent ev;
            XNextEvent(display, &ev);
            switch (ev.type) {
            case Expose:
                {
                    XRectangle r;
                    r.x = ev.xexpose.x;
                    r.y = ev.xexpose.y;
                    r.width = ev.xexpose.width;
                    r.height = ev.xexpose.height;
                    XUnionRectWithRegion(&r, region,
                             region);
                }
                break;

#ifdef OWN_WINDOW
            case ReparentNotify:
                /* set background to ParentRelative for all parents */
                if (own_window) {
                    set_transparent_background(window.
                    window);
                }
                break;

            case ConfigureNotify:
                if (own_window) {
                    /* if window size isn't what expected, set fixed size */
                    if (ev.xconfigure.width !=
                     window.width
                     || ev.xconfigure.height !=
                     window.height) {
                        if (window.width != 0
                         && window.height != 0)
                            fixed_size = 1;

                        /* clear old stuff before screwing up size and pos */
                        clear_text(1);

                        {
                            XWindowAttributes
                             attrs;
                            if (XGetWindowAttributes(display, window.window, &attrs)) {
                                window.
                                 width =
                                 attrs.
                                 width;
                                window.
                                 height
                                 =
                                 attrs.
                                 height;
                            }
                        }

                        text_width =
                         window.width -
                         border_margin * 2 - 1;
                        text_height =
                         window.height -
                         border_margin * 2 - 1;
                        if (text_width > maximum_width && maximum_width > 0)
                            text_width = maximum_width;
                    }

                    
/* if position isn't what expected, set fixed pos, total_updates
                     * avoids setting fixed_pos when window is set to weird locations
                     * when started */

                    
/*if (total_updates >= 2 this is broken
                     && !fixed_pos
                     && (window.x != ev.xconfigure.x
                        || window.y !=
                        ev.xconfigure.y)
                     && (ev.xconfigure.x != 0
                        || ev.xconfigure.y != 0)) {
                        fixed_pos = 1;
                }*/

                    set_font();
                }
                break;

            case ButtonPress:
                if (own_window)
                {
                 /* forward the click to the desktop window */
                 XUngrabPointer(display, ev.xbutton.time);
                 ev.xbutton.window = window.desktop;
                 XSendEvent(display, ev.xbutton.window, False, ButtonPressMask, &ev);
                }
                break;

             case ButtonRelease:
                                if (own_window)
                                {
                                    /* forward the release to the desktop window */
                                    ev.xbutton.window = window.desktop;
                                    XSendEvent(display, ev.xbutton.window, False, ButtonReleaseMask, &ev);
                                }
                                break;

#endif

            default:
#ifdef HAVE_XDAMAGE
                if (ev.type == event_base + XDamageNotify) {
                    XDamageNotifyEvent *dev = (XDamageNotifyEvent *) &ev;
                    XFixesSetRegion(display, part, &dev->area, 1);
                    XFixesUnionRegion(display, region2, region2, part);
                }
#endif /* HAVE_XDAMAGE */
                break;
            }
    }
#ifdef HAVE_XDAMAGE
        XDamageSubtract(display, damage, region2, None);
        XFixesSetRegion(display, region2, 0, 0);
#endif /* HAVE_XDAMAGE */

        
/* XDBE doesn't seem to provide a way to clear the back buffer without
         * interfering with the front buffer, other than passing XdbeBackground
         * to XdbeSwapBuffers. That means that if we're using XDBE, we need to
         * redraw the text even if it wasn't part of the exposed area. OTOH,
         * if we're not going to call draw_stuff at all, then no swap happens
         * and we can safely do nothing.
         */


        if (!XEmptyRegion(region)) {
#ifdef HAVE_XDBE
            if (use_xdbe) {
                XRectangle r;
                r.x = text_start_x - border_margin;
                r.y = text_start_y - border_margin;
                r.width = text_width + border_margin * 2;
                r.height = text_height + border_margin * 2;
                XUnionRectWithRegion(&r, region, region);
//updates the destination region from a union of the specified rectangle and the specified source region.

        }
#endif
            XSetRegion(display, window.gc, region);
//sets the clip-mask in the GC to the specified region

#ifdef XFT
            if (use_xft) {
                XftDrawSetClip(window.xftdraw, region);
//X核心支持xft的显示

            }
#endif
#endif /* X11 */
            draw_stuff();
#ifdef X11
            XDestroyRegion(region);
            region = XCreateRegion();
        }
#endif /* X11 */

#ifdef SIGNAL_BLOCKING
        /* unblock signals of interest and let handler fly */
//解除我们感兴趣信号的阻塞,由我们处理

        if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
            CRIT_ERR("unable to sigprocmask()");
#endif

        switch(g_signal_pending) {
        case SIGUSR1:
            {
            ERR("received SIGUSR1. reloading the config file.");
            reload_config();
//我们定义的一个重新加载config file的信号

            break;
            }
        case SIGINT:
        case SIGTERM:
            {
            ERR("received SIGINT or SIGTERM to terminate. bye!");
            clean_up();
#ifdef X11
            XDestroyRegion(region);
            region = NULL;
#endif /* X11 */
            return; /* return from main_loop */
            /*break;*/
            }
        default:
            {
            
/* Reaching here means someone set a signal( SIGXXXX, signal_handler )
             * but didn't write any code to deal with it. if you don't want to
             * handle a signal, don't set a handler on it in the first place. */

            if (g_signal_pending)
                ERR("ignoring signal (%d)", g_signal_pending);
            break;
            }
        }
        g_signal_pending=0;
    
    }
#if defined(X11) && defined(HAVE_XDAMAGE)
    XDamageDestroy(display, damage);
    XFixesDestroyRegion(display, region2);
    XFixesDestroyRegion(display, part);
    XDestroyRegion(region);
    region = NULL;
#endif /* X11 && HAVE_XDAMAGE */
}

阅读(3682) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~