window_lnx.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 914 行 · 第 1/2 页

SVN-BASE
914
字号
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "_highgui.h"

#ifndef WIN32

#include <Xm/Xm.h>
#include <Xm/PanedW.h>
#include <Xm/DrawingA.h>
#include <Xm/RowColumn.h>
#include <Xm/Scale.h>
#include <X11/keysym.h>
#include <X11/extensions/XShm.h>
#include <sys/ipc.h>
#include <sys/shm.h>

struct CvWindow;

typedef struct CvTrackbar
{
    int signature;
    Widget widget;
    char* name;
    CvTrackbar* next;
    CvWindow* parent;
    int* data;
    int pos;
    int maxval;
    void (*notify)(int);
}
CvTrackbar;


typedef struct CvWindow
{
    int signature;
    Widget area;
    Widget frame;
    Widget paned;
    Widget trackbars;
    char* name;
    CvWindow* prev;
    CvWindow* next;
    
    XShmSegmentInfo* xshmseg;

    GC gc;
    XImage* image;
    XImage* dst_image;
    int converted;
    int last_key;
    int flags;

    CvMouseCallback on_mouse;

    struct
    {
        int pos;
        int rows;
        CvTrackbar* first;
    }
    toolbar;
}
CvWindow;


//#ifndef NDEBUG
#define Assert(exp)                                             \
if( !(exp) )                                                    \
{                                                               \
    printf("Assertion: %s  %s: %d\n", #exp, __FILE__, __LINE__);\
    assert(exp);                                                \
}

static void icvPutImage( CvWindow* window );
static void icvCloseWindow( Widget w, XEvent* event, String* params, Cardinal* num_params );
static void icvDrawingAreaCallback( Widget widget, XtPointer client_data, XtPointer call_data);
static void icvTrackbarJumpProc( Widget w, XtPointer client_data, XtPointer call_data );

static Widget       topLevel;
static XtAppContext appContext;
static Atom         wm_delete_window;
static XtActionsRec actions[] = { { "quit", icvCloseWindow  }, { 0, 0 } };
static XtTranslations translations;

static int             last_key;
static XtIntervalId    timer = 0;
Widget cvvTopLevelWidget = 0;

static CvWindow* hg_windows = 0;


HIGHGUI_IMPL int cvInitSystem( int argc, char** argv )
{
    static int wasInitialized = 0;    

    // check initialization status
    if( !wasInitialized )
    {
        hg_windows = 0;

        topLevel = XtAppInitialize( &appContext, "HighGUI",
                                    (XrmOptionDescList) NULL, 0, &argc, argv,
                                    (String *) NULL, (ArgList) NULL, 0);
        XtAppAddActions(appContext, actions, XtNumber(actions));
        wm_delete_window = XInternAtom(XtDisplay(topLevel),"WM_DELETE_WINDOW",False);
    
        translations = XtParseTranslationTable("<Message>WM_PROTOCOLS:quit()");
        wasInitialized = 1;
    }

    return HG_OK;
}

static CvWindow* icvFindWindowByName( const char* name )
{
    CvWindow* window = hg_windows;

    for( ; window != 0 && strcmp( name, window->name) != 0; window = window->next )
        ;

    return window;
}

static CvWindow* icvWindowByWidget( Widget widget )
{
    CvWindow* window = hg_windows;

    while( window != 0 && window->area != widget &&
           window->frame != widget && window->paned != widget )
        window = window->next;

    return window;
}


HIGHGUI_IMPL int cvNamedWindow( const char* name, int flags )
{
    int result = 0;
    CV_FUNCNAME( "cvNamedWindow" );

    __BEGIN__;

    CvWindow* window;
    int len, n;
    Arg args[16];

    cvInitSystem(0,0);

    if( !name )
        CV_ERROR( CV_StsNullPtr, "NULL name string" );

    // Check the name in the storage
    if( icvFindWindowByName( name ) != 0 )
    {
        result = 1;
        EXIT;
    }

    len = strlen(name);
    CV_CALL( window = (CvWindow*)cvAlloc(sizeof(CvWindow) + len + 1));
    memset( window, 0, sizeof(*window));

    window->signature = HG_WINDOW_SIGNATURE;

    n = 0;
    XtSetArg( args[n], XmNwidth, 100 ); n++;
    XtSetArg( args[n], XmNheight, 100 ); n++;
    
    window->frame = XtCreatePopupShell( name,
                        topLevelShellWidgetClass, topLevel,
                        args, n );
    n = 0;
    XtSetArg( args[n], XmNorientation, XmVERTICAL ); n++;
    window->paned = XmCreatePanedWindow( window->frame, "pane", args, n );
    n = 0;
    XtSetArg( args[n], XmNorientation, XmVERTICAL ); n++;
    XtSetArg( args[n], XmNpacking, XmPACK_COLUMN ); n++;
    window->trackbars = XmCreateRowColumn( window->paned, "trackbars", args, n );
    XtManageChild( window->trackbars );

    n = 0;
    window->area = XmCreateDrawingArea( window->paned, "area", args, n);
    XtAddCallback( window->area, XmNinputCallback, icvDrawingAreaCallback, window );
    XtAddCallback( window->area, XmNexposeCallback, icvDrawingAreaCallback, window );
    
    XtManageChild( window->area );
    XtManageChild( window->paned );
                                
    window->name = (char*)(window + 1);
    memcpy( window->name, name, len + 1 );
    window->flags = flags;
    window->signature = HG_WINDOW_SIGNATURE;
    window->image = 0;
    window->gc = 0;
    window->last_key = 0;
    
    window->on_mouse = 0;

    memset( &window->toolbar, 0, sizeof(window->toolbar));

    window->next = hg_windows;
    window->prev = 0;
    if( hg_windows )
        hg_windows->prev = window;
    hg_windows = window;
    
    window->xshmseg = (XShmSegmentInfo*)cvAlloc(sizeof(XShmSegmentInfo));
    memset( window->xshmseg, 0, sizeof(*window->xshmseg) );
    
    XtPopup(window->frame, XtGrabNone);
    /*XMapRaised( XtDisplay(window->frame), window->frame );*/

    XtOverrideTranslations( window->frame, XtParseTranslationTable("<Message>WM_PROTOCOLS:quit()") );

    result = 1;
    __END__;

    return result;
}


static void icvDeleteWindow( CvWindow* window )
{
    CvTrackbar* trackbar;
    
    if( window->prev )
        window->prev->next = window->next;
    else
        hg_windows = window->next;

    if( window->next )
        window->next->prev = window->prev;

    window->prev = window->next = 0;

    if( window->image )
    {
        XImage* image = window->image;
        window->image = 0;
        cvFree( (void**)&image->data );
        XDestroyImage( image );
    }
    
    if( window->dst_image )
    {
        /*XImage* image = window->dst_image;
        window->dst_image = 0;
        cvFree( (void**)&image->data );
        XDestroyImage( image );*/

        XShmDetach( XtDisplay(window->area), window->xshmseg );
        XDestroyImage( window->dst_image );
        shmdt( window->xshmseg->shmaddr );
        shmctl( window->xshmseg->shmid, IPC_RMID, NULL );        
        window->dst_image = 0;
    }

    if( window->gc )
        ;

    XtDestroyWidget( window->frame );
    
    for( trackbar = window->toolbar.first; trackbar != 0; )
    {
        CvTrackbar* next = trackbar->next;
        cvFree( (void**)&trackbar );
        trackbar = next;
    }
    

    cvFree( (void**)&window->xshmseg ); 
    cvFree( (void**)&window );
}


HIGHGUI_IMPL void cvDestroyWindow( const char* name )
{
    CV_FUNCNAME( "cvDestroyWindow" );
    
    __BEGIN__;

    CvWindow* window;

    if(!name)
        CV_ERROR( CV_StsNullPtr, "NULL name string" );

    window = icvFindWindowByName( name );
    if( !window )
        EXIT;

    icvDeleteWindow( window );

    __END__;
}


HIGHGUI_IMPL void
cvDestroyAllWindows( void )
{
    while( hg_windows )
    {
        CvWindow* window = hg_windows;
        icvDeleteWindow( window );
    }
}



HIGHGUI_IMPL void
cvShowImage( const char* name, const CvArr* arr )
{
    CV_FUNCNAME( "cvShowImage" );

    __BEGIN__;
    
    CvWindow* window;
    int origin = 0;
    CvMat stub, dst, *image;

    if( !name )
        CV_ERROR( CV_StsNullPtr, "NULL name" );

    window = icvFindWindowByName(name);
    if( !window || !arr )
        EXIT; // keep silence here.

    if( CV_IS_IMAGE_HDR( arr ))
        origin = ((IplImage*)arr)->origin;
    
    CV_CALL( image = cvGetMat( arr, &stub ));

    if( !window->image )
        cvResizeWindow( name, image->width, image->height );

	if( window->image &&
        (window->image->width  != image->width  ||
         window->image->height != image->height ||
         window->image->bytes_per_line != image->step ||
         window->image->depth  != CV_ELEM_SIZE(image->type)) )
    {
        cvFree( (void**)&window->image->data );
        XDestroyImage( window->image );
        window->image = 0;
    }

    if( !window->image )
    {
        Display* display = XtDisplay(window->frame);
		int   depth = DefaultDepth(display, 0);
        int   step = (image->width * depth / 8 + 3) & ~3;
        char* data = (char*)cvAlloc( step * image->height );
        window->image = XCreateImage( display,
                                      CopyFromParent,
                                      depth,
                                      ZPixmap, 0, data, image->width, image->height,
                                      8, step );
        window->image->bits_per_pixel = window->image->depth;
                
        if( window->flags )
            XtVaSetValues( window->area,
                           XtNwidth, image->width,
                           XtNheight, image->height, 0 );
    }

    cvInitMatHeader( &dst, image->height, image->width,
                     CV_8U + ((window->image->depth/8)-1)*8, 
                     window->image->data, window->image->bytes_per_line );
    cvConvertImage( image, &dst, origin != 0 );
    icvPutImage( window );

    __END__;
}


HIGHGUI_IMPL void cvResizeWindow(const char* name, int width, int height )
{
    CV_FUNCNAME( "cvResizeWindow" );

    __BEGIN__;
    
    CvWindow* window;
    CvTrackbar* trackbar;

    if( !name )
        CV_ERROR( CV_StsNullPtr, "NULL name" );

    window = icvFindWindowByName(name);
    if(!window)
        EXIT;

    for( trackbar = window->toolbar.first; trackbar != 0; trackbar = trackbar->next )
        height += 10;
    if( hg_windows->flags )
        XtVaSetValues( window->area, 
                       XtNminWidth, width, XtNmaxWidth, width,
                       XtNminHeight, height, XtNmaxHeight, height, 0 );
    XtVaSetValues( window->frame, XtNwidth, width, XtNheight, height, 0 );

    __END__;
}


HIGHGUI_IMPL void cvMoveWindow( const char* name, int x, int y )
{
    CV_FUNCNAME( "cvMoveWindow" );

    __BEGIN__;

    CvWindow* window;

    if( !name )
        CV_ERROR( CV_StsNullPtr, "NULL name" );

    window = icvFindWindowByName(name);
    if(!window)
        EXIT;
    

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?