examples/ipc/sharedmemory/dialog.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the examples of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "dialog.h"
       
    43 #include <QFileDialog>
       
    44 #include <QBuffer>
       
    45 #include <QtCore/QDebug>
       
    46 
       
    47 /*!
       
    48   \class Dialog
       
    49 
       
    50   \brief This class is a simple example of how to use QSharedMemory.
       
    51 
       
    52   It is a simple dialog that presents a few buttons. To compile the
       
    53   example, run make in qt/examples/ipc. Then run the executable twice
       
    54   to create two processes running the dialog. In one of the processes,
       
    55   press the button to load an image into a shared memory segment, and
       
    56   then select an image file to load. Once the first process has loaded
       
    57   and displayed the image, in the second process, press the button to
       
    58   read the same image from shared memory. The second process displays
       
    59   the same image loaded from its new loaction in shared memory.
       
    60 */
       
    61 
       
    62 /*!
       
    63   The class contains a data member \l {QSharedMemory} {sharedMemory},
       
    64   which is initialized with the key "QSharedMemoryExample" to force
       
    65   all instances of Dialog to access the same shared memory segment.
       
    66   The constructor also connects the clicked() signal from each of the
       
    67   three dialog buttons to the slot function appropriate for handling
       
    68   each button.
       
    69 */
       
    70 //! [0]
       
    71 Dialog::Dialog(QWidget *parent)
       
    72   : QDialog(parent), sharedMemory("QSharedMemoryExample")
       
    73 {
       
    74     ui.setupUi(this);
       
    75     connect(ui.loadFromFileButton, SIGNAL(clicked()), SLOT(loadFromFile()));
       
    76     connect(ui.loadFromSharedMemoryButton,
       
    77 	    SIGNAL(clicked()),
       
    78 	    SLOT(loadFromMemory()));
       
    79     setWindowTitle(tr("SharedMemory Example"));
       
    80 }
       
    81 //! [0]
       
    82 
       
    83 /*!
       
    84   This slot function is called when the \tt {Load Image From File...}
       
    85   button is pressed on the firs Dialog process. First, it tests
       
    86   whether the process is already connected to a shared memory segment
       
    87   and, if so, detaches from that segment. This ensures that we always
       
    88   start the example from the beginning if we run it multiple times
       
    89   with the same two Dialog processes. After detaching from an existing
       
    90   shared memory segment, the user is prompted to select an image file.
       
    91   The selected file is loaded into a QImage. The QImage is displayed
       
    92   in the Dialog and streamed into a QBuffer with a QDataStream.
       
    93 
       
    94   Next, it gets a new shared memory segment from the system big enough
       
    95   to hold the image data in the QBuffer, and it locks the segment to
       
    96   prevent the second Dialog process from accessing it. Then it copies
       
    97   the image from the QBuffer into the shared memory segment. Finally,
       
    98   it unlocks the shared memory segment so the second Dialog process
       
    99   can access it.
       
   100 
       
   101   After this function runs, the user is expected to press the \tt
       
   102   {Load Image from Shared Memory} button on the second Dialog process.
       
   103 
       
   104   \sa loadFromMemory()
       
   105  */
       
   106 //! [1]
       
   107 void Dialog::loadFromFile()
       
   108 {
       
   109     if (sharedMemory.isAttached())
       
   110         detach();
       
   111 
       
   112     ui.label->setText(tr("Select an image file"));
       
   113     QString fileName = QFileDialog::getOpenFileName(0, QString(), QString(),
       
   114                                         tr("Images (*.png *.xpm *.jpg)"));
       
   115     QImage image;
       
   116     if (!image.load(fileName)) {
       
   117         ui.label->setText(tr("Selected file is not an image, please select another."));
       
   118         return;
       
   119     }
       
   120     ui.label->setPixmap(QPixmap::fromImage(image));
       
   121 //! [1] //! [2]
       
   122 
       
   123     // load into shared memory
       
   124     QBuffer buffer;
       
   125     buffer.open(QBuffer::ReadWrite);
       
   126     QDataStream out(&buffer);
       
   127     out << image;
       
   128     int size = buffer.size();
       
   129 
       
   130     if (!sharedMemory.create(size)) {
       
   131         ui.label->setText(tr("Unable to create shared memory segment."));
       
   132         return;
       
   133     }
       
   134     sharedMemory.lock();
       
   135     char *to = (char*)sharedMemory.data();
       
   136     const char *from = buffer.data().data();
       
   137     memcpy(to, from, qMin(sharedMemory.size(), size));
       
   138     sharedMemory.unlock();
       
   139 }
       
   140 //! [2]
       
   141 
       
   142 /*!
       
   143   This slot function is called in the second Dialog process, when the
       
   144   user presses the \tt {Load Image from Shared Memory} button. First,
       
   145   it attaches the process to the shared memory segment created by the
       
   146   first Dialog process. Then it locks the segment for exclusive
       
   147   access, copies the image data from the segment into a QBuffer, and
       
   148   streams the QBuffer into a QImage. Then it unlocks the shared memory
       
   149   segment, detaches from it, and finally displays the QImage in the
       
   150   Dialog.
       
   151 
       
   152   \sa loadFromFile()
       
   153  */
       
   154 //! [3]
       
   155 void Dialog::loadFromMemory()
       
   156 {
       
   157     if (!sharedMemory.attach()) {
       
   158         ui.label->setText(tr("Unable to attach to shared memory segment.\n" \
       
   159 			     "Load an image first."));
       
   160         return;
       
   161     }
       
   162 
       
   163     QBuffer buffer;
       
   164     QDataStream in(&buffer);
       
   165     QImage image;
       
   166 
       
   167     sharedMemory.lock();
       
   168     buffer.setData((char*)sharedMemory.constData(), sharedMemory.size());
       
   169     buffer.open(QBuffer::ReadOnly);
       
   170     in >> image;
       
   171     sharedMemory.unlock();
       
   172 
       
   173     sharedMemory.detach();
       
   174     ui.label->setPixmap(QPixmap::fromImage(image));
       
   175 }
       
   176 //! [3]
       
   177 
       
   178 /*!
       
   179   This private function is called by the destructor to detach the
       
   180   process from its shared memory segment. When the last process
       
   181   detaches from a shared memory segment, the system releases the
       
   182   shared memory.
       
   183  */
       
   184 void Dialog::detach()
       
   185 {
       
   186     if (!sharedMemory.detach()) 
       
   187         ui.label->setText(tr("Unable to detach from shared memory."));
       
   188 }
       
   189