<commit_before>#include "emboxvcwindowsurface.h"
#include <QtCore/qdebug.h>
#include <QtGui/private/qapplication_p.h>
#include <QWindowSystemInterface>
#include <QMouseEvent>

QT_BEGIN_NAMESPACE

static QList<QEmboxVCWindowSurface*> __emboxVCcollection;
extern QEmboxVC *globalEmboxVC;

//static QEmboxVCWindowSurface * __emboxVC(struct vc *vc) {
//	for (int i = 0; i < __emboxVCcollection.size(); ++i) {
//		QEmboxVCWindowSurface *emvc = __emboxVCcollection.at(i);
//		if (&(emvc->emboxVC) == vc) {
//			return emvc;
//		}
//	}
//
//	return NULL;
//}

static void flushAll() {
	QRegion region;
	QPoint point;

	for (int i = 0; i < __emboxVCcollection.size(); ++i) {
		__emboxVCcollection.at(i)->flush(0, region, point);
	}
}

static int visibleWidgetsCount() {
	int cnt = 0;
	for (int i = 0; i < __emboxVCcollection.size(); ++i) {
		cnt += __emboxVCcollection.at(i)->window()->isVisible() ? 1 : 0;
	}
	return cnt;
}

static void __emboxVCsetMode(struct vc *vc, int mode) {
	globalEmboxVC->emboxVCvisualized = mode;
}

static void __visualization(struct vc *vc, struct fb_info *info) {
	Q_UNUSED(info);

	QEmboxVCWindowSurface *surf;

	__emboxVCsetMode(vc, 1);
	//surf = __emboxVC(vc);
	//surf->flush(NULL, region, point);
	flushAll();

	foreach (QWidget *widget, QApplication::allWidgets()) {
		widget->update();
	}
}

QEmboxVCMouseHandler::QEmboxVCMouseHandler() {
	int pipefd[2];

	if (pipe(pipefd) < 0) {
		return;
	}

	mouseFD = pipefd[0];
	inputFD = pipefd[1];

	fcntl(mouseFD, F_SETFD, O_NONBLOCK);
	fcntl(inputFD, F_SETFD, O_NONBLOCK);

    mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this);
    connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData()));
}

QEmboxVCMouseHandler::~QEmboxVCMouseHandler() {

}

void QEmboxVCMouseHandler::storeData(void *data, int datalen) {
	write(inputFD, data, datalen);
}

void QEmboxVCMouseHandler::readMouseData() {
	struct vc *vc;
	struct input_event ev;
	short x, y;
	int bstate;
	QEmboxVC *emvc;

	while (read(mouseFD, &vc, sizeof(struct vc *)) > 0) {

		read(mouseFD, &ev, sizeof(struct input_event));

		emvc = globalEmboxVC;

		bstate = Qt::NoButton;

		if (ev.type & 1) {
			bstate = Qt::LeftButton;
		} else if (ev.type & 2) {
			bstate = Qt::RightButton;
		}

		x = ev.value >> 16;
		y = ev.value & 0xffff;

		emvc->mouseX += x;
		emvc->mouseY += -y;

		int xres = emvc->emboxVC.fb->var.xres;
		int yres = emvc->emboxVC.fb->var.yres;

		emvc->mouseX = emvc->mouseX > 0 ? emvc->mouseX : 0;
		emvc->mouseY = emvc->mouseY > 0 ? emvc->mouseY : 0;

		emvc->mouseX = emvc->mouseX > xres ? xres : emvc->mouseX;
		emvc->mouseY = emvc->mouseY > yres ? yres : emvc->mouseY;

		QWindowSystemInterface::handleMouseEvent(0, QPoint(emvc->mouseX, emvc->mouseY),
				QPoint(emvc->mouseX, emvc->mouseY), Qt::MouseButtons(bstate));

		if (!emvc->emboxVC.fb || !emvc->emboxVCvisualized) {
			return;
		}

		emvc->cursor->emboxCursorRedraw(emvc->emboxVC.fb, emvc->mouseX, emvc->mouseY);
	}
}

QEmboxVCKeyboardHandler::QEmboxVCKeyboardHandler() {
	int pipefd[2];

	if (pipe(pipefd) < 0) {
		return;
	}

	keyboardFD = pipefd[0];
	inputFD = pipefd[1];

	fcntl(keyboardFD, F_SETFD, O_NONBLOCK);
	fcntl(inputFD, F_SETFD, O_NONBLOCK);

    keyboardNotifier = new QSocketNotifier(keyboardFD, QSocketNotifier::Read, this);
    connect(keyboardNotifier, SIGNAL(activated(int)),this, SLOT(readKeyboardData()));
}

QEmboxVCKeyboardHandler::~QEmboxVCKeyboardHandler() {

}

void QEmboxVCKeyboardHandler::storeData(void *data, int datalen) {
	write(inputFD, data, datalen);
}

void QEmboxVCKeyboardHandler::readKeyboardData() {
	struct vc *vc;
	struct input_event ev;

	while (read(keyboardFD, &vc, sizeof(struct vc *)) > 0) {
		QEvent::Type type;
		unsigned char ascii[4];
		Qt::KeyboardModifiers modifier = 0;

		read(keyboardFD, &ev, sizeof(struct input_event));

		type = ev.type & KEY_PRESSED ? QEvent::KeyPress : QEvent::KeyRelease;

		if (ev.value & SHIFT_PRESSED) {
			modifier = Qt::ShiftModifier;
		} else if (ev.value & ALT_PRESSED) {
			modifier = Qt::AltModifier;
		} else if (ev.value & CTRL_PRESSED) {
			modifier = Qt::ControlModifier;
		}

		int len = keymap_to_ascii(&ev, ascii);

//		QString key
//		for (int i = 0; i < len; i++) {
//			key += QChar(ascii[i]);
//		}

		QWindowSystemInterface::handleKeyEvent(0, type, ascii[0], modifier, QString(QChar(ascii[0])));
	}
}

static void __handle_input_event(struct vc *vc, struct input_event *ev) {
	QEmboxVC *emvc = globalEmboxVC;

	if (ev->devtype == INPUT_DEV_MOUSE) {
		emvc->mouseHandler->storeData(&vc, sizeof(struct vc *));
		emvc->mouseHandler->storeData(ev, sizeof(struct input_event));
	} else if (ev->devtype == INPUT_DEV_KBD) {
		emvc->keyboardHandler->storeData(&vc, sizeof(struct vc *));
		emvc->keyboardHandler->storeData(ev, sizeof(struct input_event));
	}
}

static void __scheduleDevisualization(struct vc *vc) {
	printf(">>__scheduleDevisualization\n");
	__emboxVCsetMode(vc, 0);

	mpx_devisualized(vc);
}

QEmboxVC::QEmboxVC()
    : emboxVCvisualized(0), mouseX(0), mouseY(0)
{
	cursor = new QEmboxCursor();

	mouseHandler = new QEmboxVCMouseHandler();
	keyboardHandler = new QEmboxVCKeyboardHandler();

	emboxVCcallbacks.visualized = __visualization;
	emboxVCcallbacks.schedule_devisualization = __scheduleDevisualization;
	emboxVCcallbacks.handle_input_event = __handle_input_event;

	emboxVC.callbacks = &emboxVCcallbacks;
	emboxVC.name = "emboxvc";

	mpx_register_vc(&emboxVC);
}

QEmboxVC::~QEmboxVC() {
}

QEmboxVCWindowSurface::QEmboxVCWindowSurface(QWidget *window)
    : QWindowSurface(window)
{
	mImage = QImage(QSize(window->width(), window->height()), QImage::Format_RGB16);

	vc = globalEmboxVC;

	__emboxVCcollection.append(this);
}

QEmboxVCWindowSurface::~QEmboxVCWindowSurface()
{
	__emboxVCcollection.removeAll(this);
}

QPaintDevice *QEmboxVCWindowSurface::paintDevice()
{
    return &mImage;
}

void QEmboxVCWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
{
    Q_UNUSED(widget);
    Q_UNUSED(region);
    Q_UNUSED(offset);

    int i, shift;

    int x = widget->pos().x();
    int y = widget->pos().y();

    if (!vc->emboxVC.fb || !vc->emboxVCvisualized) {
    	return;
    }

    int bpp = vc->emboxVC.fb->var.bits_per_pixel / 8;
    char *begin = vc->emboxVC.fb->screen_base + (y * vc->emboxVC.fb->var.xres + x) * bpp;

    /* Draw image */
    for (i = 0, shift = 0; i < mImage.height(); i++ , shift += vc->emboxVC.fb->var.xres * bpp) {
    	memcpy(begin + shift, (const void *)mImage.constScanLine(i), mImage.bytesPerLine());
    }

    /* Reset cursor on new image and redraw */
    vc->cursor->emboxCursorReset(vc->emboxVC.fb);
    vc->cursor->emboxCursorRedraw(vc->emboxVC.fb, vc->mouseX, vc->mouseY);
}

void QEmboxVCWindowSurface::resize(const QSize &size)
{
    //qDebug() << "QMinimalWindowSurface::setGeometry:" << (long)this << rect;
    //QWindowSurface::resize(size);
    //QImage::Format format = QApplicationPrivate::platformIntegration()->screens().first()->format();
    //if (mImage.size() != size)
            //[> XXX <]
        //mImage = QImage(size, QImage::Format_RGB16);
}

QEmboxVCPlatformWindow::QEmboxVCPlatformWindow(QWidget *widget)
: QPlatformWindow(widget)
{
}

QEmboxVCPlatformWindow::~QEmboxVCPlatformWindow()
{
}

WId QEmboxVCPlatformWindow::winId() const {
	return WId(1);
}

void QEmboxVCPlatformWindow::setParent(const QPlatformWindow *window) {
	//if (widget() && window->widget()) {
	//	widget()->setParent(window->widget());
	//}
}

QT_END_NAMESPACE
<commit_msg>qt: support for control characters handling<commit_after>#include "emboxvcwindowsurface.h"
#include <QtCore/qdebug.h>
#include <QtGui/private/qapplication_p.h>
#include <QWindowSystemInterface>
#include <QMouseEvent>

QT_BEGIN_NAMESPACE

/* From VNC */
static const struct {
    int keysym;
    int keycode;
} emboxKeyMap[] = {
    { 0x08, Qt::Key_Backspace },
    { 0x09, Qt::Key_Tab       },
    { 0x0d, Qt::Key_Return    },
    { 0x1b, Qt::Key_Escape    },
    { 0x63, Qt::Key_Insert    },
    { 0xff, Qt::Key_Delete    },
    { 0x50, Qt::Key_Home      },
    { 0x57, Qt::Key_End       },
    { 0x55, Qt::Key_PageUp    },
    { 0x56, Qt::Key_PageDown  },
    { 0x51, Qt::Key_Left      },
    { 0x52, Qt::Key_Up        },
    { 0x53, Qt::Key_Right     },
    { 0x54, Qt::Key_Down      },
    { 0xbe, Qt::Key_F1        },
    { 0xbf, Qt::Key_F2        },
    { 0xc0, Qt::Key_F3        },
    { 0xc1, Qt::Key_F4        },
    { 0xc2, Qt::Key_F5        },
    { 0xc3, Qt::Key_F6        },
    { 0xc4, Qt::Key_F7        },
    { 0xc5, Qt::Key_F8        },
    { 0xc6, Qt::Key_F9        },
    { 0xc7, Qt::Key_F10       },
    { 0xc8, Qt::Key_F11       },
    { 0xc9, Qt::Key_F12       },
    { 0xe1, Qt::Key_Shift     },
    { 0xe2, Qt::Key_Shift     },
    { 0xe3, Qt::Key_Control   },
    { 0xe4, Qt::Key_Control   },
    { 0xe7, Qt::Key_Meta      },
    { 0xe8, Qt::Key_Meta      },
    { 0xe9, Qt::Key_Alt       },
    { 0xea, Qt::Key_Alt       },
    { 0, 0 }
};

static QList<QEmboxVCWindowSurface*> __emboxVCcollection;
extern QEmboxVC *globalEmboxVC;

//static QEmboxVCWindowSurface * __emboxVC(struct vc *vc) {
//	for (int i = 0; i < __emboxVCcollection.size(); ++i) {
//		QEmboxVCWindowSurface *emvc = __emboxVCcollection.at(i);
//		if (&(emvc->emboxVC) == vc) {
//			return emvc;
//		}
//	}
//
//	return NULL;
//}

static void flushAll() {
	QRegion region;
	QPoint point;

	for (int i = 0; i < __emboxVCcollection.size(); ++i) {
		__emboxVCcollection.at(i)->flush(0, region, point);
	}
}

static int visibleWidgetsCount() {
	int cnt = 0;
	for (int i = 0; i < __emboxVCcollection.size(); ++i) {
		cnt += __emboxVCcollection.at(i)->window()->isVisible() ? 1 : 0;
	}
	return cnt;
}

static void __emboxVCsetMode(struct vc *vc, int mode) {
	globalEmboxVC->emboxVCvisualized = mode;
}

static void __visualization(struct vc *vc, struct fb_info *info) {
	Q_UNUSED(info);

	QEmboxVCWindowSurface *surf;

	__emboxVCsetMode(vc, 1);
	//surf = __emboxVC(vc);
	//surf->flush(NULL, region, point);
	flushAll();

	foreach (QWidget *widget, QApplication::allWidgets()) {
		widget->update();
	}
}

QEmboxVCMouseHandler::QEmboxVCMouseHandler() {
	int pipefd[2];

	if (pipe(pipefd) < 0) {
		return;
	}

	mouseFD = pipefd[0];
	inputFD = pipefd[1];

	fcntl(mouseFD, F_SETFD, O_NONBLOCK);
	fcntl(inputFD, F_SETFD, O_NONBLOCK);

    mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this);
    connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData()));
}

QEmboxVCMouseHandler::~QEmboxVCMouseHandler() {

}

void QEmboxVCMouseHandler::storeData(void *data, int datalen) {
	write(inputFD, data, datalen);
}

void QEmboxVCMouseHandler::readMouseData() {
	struct vc *vc;
	struct input_event ev;
	short x, y;
	int bstate;
	QEmboxVC *emvc;

	while (read(mouseFD, &vc, sizeof(struct vc *)) > 0) {

		read(mouseFD, &ev, sizeof(struct input_event));

		emvc = globalEmboxVC;

		bstate = Qt::NoButton;

		if (ev.type & 1) {
			bstate = Qt::LeftButton;
		} else if (ev.type & 2) {
			bstate = Qt::RightButton;
		}

		x = ev.value >> 16;
		y = ev.value & 0xffff;

		emvc->mouseX += x;
		emvc->mouseY += -y;

		int xres = emvc->emboxVC.fb->var.xres;
		int yres = emvc->emboxVC.fb->var.yres;

		emvc->mouseX = emvc->mouseX > 0 ? emvc->mouseX : 0;
		emvc->mouseY = emvc->mouseY > 0 ? emvc->mouseY : 0;

		emvc->mouseX = emvc->mouseX > xres ? xres : emvc->mouseX;
		emvc->mouseY = emvc->mouseY > yres ? yres : emvc->mouseY;

		QWindowSystemInterface::handleMouseEvent(0, QPoint(emvc->mouseX, emvc->mouseY),
				QPoint(emvc->mouseX, emvc->mouseY), Qt::MouseButtons(bstate));

		if (!emvc->emboxVC.fb || !emvc->emboxVCvisualized) {
			return;
		}

		emvc->cursor->emboxCursorRedraw(emvc->emboxVC.fb, emvc->mouseX, emvc->mouseY);
	}
}

QEmboxVCKeyboardHandler::QEmboxVCKeyboardHandler() {
	int pipefd[2];

	if (pipe(pipefd) < 0) {
		return;
	}

	keyboardFD = pipefd[0];
	inputFD = pipefd[1];

	fcntl(keyboardFD, F_SETFD, O_NONBLOCK);
	fcntl(inputFD, F_SETFD, O_NONBLOCK);

    keyboardNotifier = new QSocketNotifier(keyboardFD, QSocketNotifier::Read, this);
    connect(keyboardNotifier, SIGNAL(activated(int)),this, SLOT(readKeyboardData()));
}

QEmboxVCKeyboardHandler::~QEmboxVCKeyboardHandler() {

}

void QEmboxVCKeyboardHandler::storeData(void *data, int datalen) {
	write(inputFD, data, datalen);
}

void QEmboxVCKeyboardHandler::readKeyboardData() {
	struct vc *vc;
	struct input_event ev;

	while (read(keyboardFD, &vc, sizeof(struct vc *)) > 0) {
		QEvent::Type type;
		unsigned char ascii[4];
		int key;
		int i = 0;
		Qt::KeyboardModifiers modifier = 0;

		read(keyboardFD, &ev, sizeof(struct input_event));

		type = ev.type & KEY_PRESSED ? QEvent::KeyPress : QEvent::KeyRelease;

		if (ev.value & SHIFT_PRESSED) {
			modifier = Qt::ShiftModifier;
		} else if (ev.value & ALT_PRESSED) {
			modifier = Qt::AltModifier;
		} else if (ev.value & CTRL_PRESSED) {
			modifier = Qt::ControlModifier;
		}

		int len = keymap_to_ascii(&ev, ascii);

		while (emboxKeyMap[i].keysym != 0) {
			if (emboxKeyMap[i].keysym == ascii[i]) {
				key = emboxKeyMap[i].keycode;
				break;
			}
			i++;
		}

		QWindowSystemInterface::handleKeyEvent(0, type, key, modifier, QString(QChar(ascii[0])));
	}
}

static void __handle_input_event(struct vc *vc, struct input_event *ev) {
	QEmboxVC *emvc = globalEmboxVC;

	if (ev->devtype == INPUT_DEV_MOUSE) {
		emvc->mouseHandler->storeData(&vc, sizeof(struct vc *));
		emvc->mouseHandler->storeData(ev, sizeof(struct input_event));
	} else if (ev->devtype == INPUT_DEV_KBD) {
		emvc->keyboardHandler->storeData(&vc, sizeof(struct vc *));
		emvc->keyboardHandler->storeData(ev, sizeof(struct input_event));
	}
}

static void __scheduleDevisualization(struct vc *vc) {
	printf(">>__scheduleDevisualization\n");
	__emboxVCsetMode(vc, 0);

	mpx_devisualized(vc);
}

QEmboxVC::QEmboxVC()
    : emboxVCvisualized(0), mouseX(0), mouseY(0)
{
	cursor = new QEmboxCursor();

	mouseHandler = new QEmboxVCMouseHandler();
	keyboardHandler = new QEmboxVCKeyboardHandler();

	emboxVCcallbacks.visualized = __visualization;
	emboxVCcallbacks.schedule_devisualization = __scheduleDevisualization;
	emboxVCcallbacks.handle_input_event = __handle_input_event;

	emboxVC.callbacks = &emboxVCcallbacks;
	emboxVC.name = "emboxvc";

	mpx_register_vc(&emboxVC);
}

QEmboxVC::~QEmboxVC() {
}

QEmboxVCWindowSurface::QEmboxVCWindowSurface(QWidget *window)
    : QWindowSurface(window)
{
	mImage = QImage(QSize(window->width(), window->height()), QImage::Format_RGB16);

	vc = globalEmboxVC;

	__emboxVCcollection.append(this);
}

QEmboxVCWindowSurface::~QEmboxVCWindowSurface()
{
	__emboxVCcollection.removeAll(this);
}

QPaintDevice *QEmboxVCWindowSurface::paintDevice()
{
    return &mImage;
}

void QEmboxVCWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
{
    Q_UNUSED(widget);
    Q_UNUSED(region);
    Q_UNUSED(offset);

    int i, shift;

    int x = widget->pos().x();
    int y = widget->pos().y();

    if (!vc->emboxVC.fb || !vc->emboxVCvisualized) {
    	return;
    }

    int bpp = vc->emboxVC.fb->var.bits_per_pixel / 8;
    char *begin = vc->emboxVC.fb->screen_base + (y * vc->emboxVC.fb->var.xres + x) * bpp;

    /* Draw image */
    for (i = 0, shift = 0; i < mImage.height(); i++ , shift += vc->emboxVC.fb->var.xres * bpp) {
    	memcpy(begin + shift, (const void *)mImage.constScanLine(i), mImage.bytesPerLine());
    }

    /* Reset cursor on new image and redraw */
    vc->cursor->emboxCursorReset(vc->emboxVC.fb);
    vc->cursor->emboxCursorRedraw(vc->emboxVC.fb, vc->mouseX, vc->mouseY);
}

void QEmboxVCWindowSurface::resize(const QSize &size)
{
    //qDebug() << "QMinimalWindowSurface::setGeometry:" << (long)this << rect;
    //QWindowSurface::resize(size);
    //QImage::Format format = QApplicationPrivate::platformIntegration()->screens().first()->format();
    //if (mImage.size() != size)
            //[> XXX <]
        //mImage = QImage(size, QImage::Format_RGB16);
}

QEmboxVCPlatformWindow::QEmboxVCPlatformWindow(QWidget *widget)
: QPlatformWindow(widget)
{
}

QEmboxVCPlatformWindow::~QEmboxVCPlatformWindow()
{
}

WId QEmboxVCPlatformWindow::winId() const {
	return WId(1);
}

void QEmboxVCPlatformWindow::setParent(const QPlatformWindow *window) {
	//if (widget() && window->widget()) {
	//	widget()->setParent(window->widget());
	//}
}

QT_END_NAMESPACE
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// Author: morlovich@google.com (Maksim Orlovich)

// Unit tests for out-of-memory handling in Image class

#include "net/instaweb/rewriter/public/image.h"

#include <sys/time.h>
#include <sys/resource.h>

#include "net/instaweb/rewriter/image_types.pb.h"
#include "net/instaweb/rewriter/public/image_test_base.h"
#include "net/instaweb/util/public/dynamic_annotations.h"  // RunningOnValgrind
#include "net/instaweb/util/public/gtest.h"
#include "net/instaweb/util/public/mock_timer.h"
#include "net/instaweb/util/public/scoped_ptr.h"
#include "net/instaweb/util/public/string.h"
#include "pagespeed/kernel/base/mock_message_handler.h"

namespace net_instaweb {
namespace {

const char kLargeJpeg[] = "Large.jpg";

class ImageOomTest : public ImageTestBase {
 public:
  virtual void SetUp() {
    ImageTestBase::SetUp();

    // All of these tests need to be disabled under valgrind since
    // valgrind and setrlimit don't get along
    if (!RunningOnValgrind()) {
      getrlimit(RLIMIT_AS, &old_mem_limit_);

      // Limit ourselves to about 100 million bytes of memory --- not enough
      // to fit in the 10000x10000 image (which has 100 million pixels).
      rlimit new_mem_limit = old_mem_limit_;
      new_mem_limit.rlim_cur = 100000000;
      setrlimit(RLIMIT_AS, &new_mem_limit);
    }
  }

  virtual void TearDown() {
    if (!RunningOnValgrind()) {
      // Restore previous rlimit
      setrlimit(RLIMIT_AS, &old_mem_limit_);
    }
    ImageTestBase::TearDown();
  }

 private:
  rlimit old_mem_limit_;
};

TEST_F(ImageOomTest, BlankImageTooLarge) {
  if (RunningOnValgrind()) {
    return;
  }

#ifndef NDEBUG
  return;
#endif

  Image::CompressionOptions* options = new Image::CompressionOptions();
  // Make sure creating gigantic image fails cleanly.
  ImagePtr giant(BlankImageWithOptions(10000000, 10000, IMAGE_PNG,
                                       GTestTempDir(), &timer_,
                                       &message_handler_, options));
  EXPECT_EQ(NULL, giant.get());
}

TEST_F(ImageOomTest, BlankImageNotTooLarge) {
  if (RunningOnValgrind()) {
    return;
  }

#ifndef NDEBUG
  return;
#endif

  Image::CompressionOptions* options = new Image::CompressionOptions();
  ImagePtr not_too_large(BlankImageWithOptions(4000, 4000, IMAGE_PNG,
                                               GTestTempDir(), &timer_,
                                               &message_handler_, options));
  // Image of this size can be created.
  EXPECT_NE(static_cast<net_instaweb::Image*>(NULL), not_too_large.get());
}

TEST_F(ImageOomTest, LoadLargeJpeg) {
  if (RunningOnValgrind()) {
    return;
  }

  GoogleString buf;
  bool not_progressive = false;
  ImagePtr giant(ReadImageFromFile(IMAGE_JPEG, kLargeJpeg, &buf,
                                   not_progressive));
  // We do not rewrite JPEG images of such large size, so the input and output
  // images have the same length.
  EXPECT_EQ(buf.length(), giant->output_size());
}

TEST_F(ImageOomTest, LoadLargePng) {
  if (RunningOnValgrind()) {
    return;
  }

  GoogleString buf;
  bool not_progressive = true;
  ImagePtr image(ReadImageFromFile(IMAGE_PNG, kLarge, &buf,
                                   not_progressive));
  // PNG images needs less memory to rewrite than JPEG. After rewriting
  // this image shrinks.
  EXPECT_GT(buf.length(), image->output_size());
}

}  // namespace
}  // namespace net_instaweb
<commit_msg>Backport change r4228 to branch 32.<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// Author: morlovich@google.com (Maksim Orlovich)

// Unit tests for out-of-memory handling in Image class

#include "net/instaweb/rewriter/public/image.h"

#include <sys/time.h>
#include <sys/resource.h>

#include "net/instaweb/rewriter/image_types.pb.h"
#include "net/instaweb/rewriter/public/image_test_base.h"
#include "net/instaweb/util/public/dynamic_annotations.h"  // RunningOnValgrind
#include "net/instaweb/util/public/gtest.h"
#include "net/instaweb/util/public/mock_timer.h"
#include "net/instaweb/util/public/scoped_ptr.h"
#include "net/instaweb/util/public/string.h"
#include "pagespeed/kernel/base/mock_message_handler.h"

namespace net_instaweb {
namespace {

const char kLargeJpeg[] = "Large.jpg";

class ImageOomTest : public ImageTestBase {
 public:
  virtual void SetUp() {
    ImageTestBase::SetUp();

    // All of these tests need to be disabled under valgrind since
    // valgrind and setrlimit don't get along
    if (!RunningOnValgrind()) {
      getrlimit(RLIMIT_AS, &old_mem_limit_);

      // Limit ourselves to about 100 million bytes of memory --- not enough
      // to fit in the 10000x10000 image (which has 100 million pixels).
      rlimit new_mem_limit = old_mem_limit_;
      new_mem_limit.rlim_cur = 100000000;
      setrlimit(RLIMIT_AS, &new_mem_limit);
    }
  }

  virtual void TearDown() {
    if (!RunningOnValgrind()) {
      // Restore previous rlimit
      setrlimit(RLIMIT_AS, &old_mem_limit_);
    }
    ImageTestBase::TearDown();
  }

 private:
  rlimit old_mem_limit_;
};

TEST_F(ImageOomTest, BlankImageTooLarge) {
  if (RunningOnValgrind()) {
    return;
  }

#ifndef NDEBUG
  return;
#endif

  Image::CompressionOptions* options = new Image::CompressionOptions();
  // Make sure creating gigantic image fails cleanly.
  ImagePtr giant(BlankImageWithOptions(10000000, 10000, IMAGE_PNG,
                                       GTestTempDir(), &timer_,
                                       &message_handler_, options));
  EXPECT_EQ(NULL, giant.get());
}

TEST_F(ImageOomTest, BlankImageNotTooLarge) {
  if (RunningOnValgrind()) {
    return;
  }

#ifndef NDEBUG
  return;
#endif

  Image::CompressionOptions* options = new Image::CompressionOptions();
  ImagePtr not_too_large(BlankImageWithOptions(4096, 2048, IMAGE_PNG,
                                               GTestTempDir(), &timer_,
                                               &message_handler_, options));
  // Image of this size can be created.
  EXPECT_NE(static_cast<net_instaweb::Image*>(NULL), not_too_large.get());
}

TEST_F(ImageOomTest, LoadLargeJpeg) {
  if (RunningOnValgrind()) {
    return;
  }

  GoogleString buf;
  bool not_progressive = false;
  ImagePtr giant(ReadImageFromFile(IMAGE_JPEG, kLargeJpeg, &buf,
                                   not_progressive));
  // We do not rewrite JPEG images of such large size, so the input and output
  // images have the same length.
  EXPECT_EQ(buf.length(), giant->output_size());
}

TEST_F(ImageOomTest, LoadLargePng) {
  if (RunningOnValgrind()) {
    return;
  }

  GoogleString buf;
  bool not_progressive = true;
  ImagePtr image(ReadImageFromFile(IMAGE_PNG, kLarge, &buf,
                                   not_progressive));
  // PNG images needs less memory to rewrite than JPEG. After rewriting
  // this image shrinks.
  EXPECT_GT(buf.length(), image->output_size());
}

}  // namespace
}  // namespace net_instaweb
<|endoftext|>


<commit_before>//*****************************************************************************
// Copyright 2017-2018 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//*****************************************************************************

#include <cstddef>
#include <memory>
#include <vector>

#include "op/conv.hpp"

#include "ngraph/op/add.hpp"
#include "ngraph/op/broadcast.hpp"
#include "ngraph/op/concat.hpp"
#include "ngraph/op/convolution.hpp"
#include "ngraph/op/slice.hpp"

#include "ngraph/frontend/onnx_import/exceptions.hpp"
#include "ngraph/frontend/onnx_import/op/conv.hpp"
#include "ngraph/frontend/onnx_import/utils/broadcasting.hpp"
#include "ngraph/frontend/onnx_import/utils/convpool.hpp"

namespace ngraph
{
    namespace onnx_import
    {
        namespace op
        {
            namespace
            {
                std::shared_ptr<ngraph::op::Op>
                    make_ng_convolution(const std::shared_ptr<ngraph::Node>& data,
                                        const std::shared_ptr<ngraph::Node>& filters,
                                        const ngraph::Strides& strides,
                                        const ngraph::Strides& dilations,
                                        const ngraph::CoordinateDiff& padding_below,
                                        const ngraph::CoordinateDiff& padding_above,
                                        int groups)
                {
                    if (groups > 1)
                    {
                        // Split one convolution op to N ops where N is the number of groups
                        // and concat results after computation.
                        // reference: https://github.com/NervanaSystems/ngraph-mxnet/blob/fdd692/src/ngraph/ngraph_emitter.cc#L822-L856
                        std::size_t n_data_channels{data->get_shape().at(1)};
                        std::size_t n_filters_channels{filters->get_shape().at(0)};
                        // TODO: ensure n_data_channels % groups = 0
                        std::size_t data_group_size{n_data_channels / groups};
                        std::size_t filters_group_size{n_filters_channels / groups};
                        NodeVector convolution_nodes;

                        // initial bounds for splice
                        std::vector<std::size_t> data_lower_bounds(data->get_shape().size());
                        std::vector<std::size_t> data_upper_bounds{data->get_shape()};
                        std::vector<std::size_t> filters_lower_bounds(filters->get_shape().size());
                        std::vector<std::size_t> filters_upper_bounds{filters->get_shape()};

                        for (std::size_t group{0}; group < groups; ++group)
                        {
                            // slice data
                            data_lower_bounds[1] = group * data_group_size;
                            data_upper_bounds[1] = (group + 1) * data_group_size;
                            auto sliced_data = std::make_shared<ngraph::op::Slice>(
                                data, data_lower_bounds, data_upper_bounds);
                            // slice filters
                            filters_lower_bounds[0] = group * filters_group_size;
                            filters_upper_bounds[0] = (group + 1) * filters_group_size;
                            auto sliced_filters = std::make_shared<ngraph::op::Slice>(
                                filters, filters_lower_bounds, filters_upper_bounds);

                            convolution_nodes.push_back(
                                std::make_shared<ngraph::op::Convolution>(sliced_data,
                                                                          sliced_filters,
                                                                          strides,
                                                                          dilations,
                                                                          padding_below,
                                                                          padding_above));
                        }
                        std::size_t concatenation_axis = 1;
                        return std::make_shared<ngraph::op::Concat>(convolution_nodes,
                                                                    concatenation_axis);
                    }
                    else
                    {
                        return std::make_shared<ngraph::op::Convolution>(
                            data, filters, strides, dilations, padding_below, padding_above);
                    }
                }

            } // namespace

            NodeVector conv(const Node& node)
            {
                const NodeVector& inputs = node.get_ng_inputs();
                auto data = inputs.at(0);
                auto filters = inputs.at(1);

                int groups{node.get_attribute_value<int>("group", 1)};

                // TODO: update to ASSERTION CHECK
                if (groups < 0 || groups > data->get_shape().at(1) ||
                    groups > filters->get_shape().at(0))
                {
                    throw error::parameter::Value{"Conv",
                                                  node.get_name(),
                                                  "incorrect value of 'group' attribute: " +
                                                      std::to_string(groups)};
                }

                auto strides = convpool::get_strides(node);
                auto dilations = convpool::get_dilations(node);
                auto paddings = convpool::get_pads(node);
                const auto& padding_below = paddings.first;
                const auto& padding_above = paddings.second;

                auto conv_node = make_ng_convolution(
                    data, filters, strides, dilations, padding_below, padding_above, groups);

                // no bias param
                if (inputs.size() < 3)
                {
                    return {conv_node};
                }

                auto bias = inputs.at(2);
                const Shape& new_shape = conv_node->get_shape();

                auto broadcasted_bias = std::make_shared<ngraph::op::Broadcast>(
                    bias, new_shape, calculate_broadcast_axes(new_shape, bias->get_shape(), 1));
                return {std::make_shared<ngraph::op::Add>(conv_node, broadcasted_bias)};
            }

        } // namespace op

    } // namespace onnx_import

} // namespace ngraph
<commit_msg>Fix for Conv op (#1556)<commit_after>//*****************************************************************************
// Copyright 2017-2018 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//*****************************************************************************

#include <cstddef>
#include <memory>
#include <vector>

#include "op/conv.hpp"

#include "ngraph/op/add.hpp"
#include "ngraph/op/broadcast.hpp"
#include "ngraph/op/concat.hpp"
#include "ngraph/op/convolution.hpp"
#include "ngraph/op/slice.hpp"

#include "ngraph/frontend/onnx_import/exceptions.hpp"
#include "ngraph/frontend/onnx_import/op/conv.hpp"
#include "ngraph/frontend/onnx_import/utils/broadcasting.hpp"
#include "ngraph/frontend/onnx_import/utils/convpool.hpp"

namespace ngraph
{
    namespace onnx_import
    {
        namespace op
        {
            namespace
            {
                std::shared_ptr<ngraph::op::Op>
                    make_ng_convolution(const std::shared_ptr<ngraph::Node>& data,
                                        const std::shared_ptr<ngraph::Node>& filters,
                                        const ngraph::Strides& strides,
                                        const ngraph::Strides& dilations,
                                        const ngraph::CoordinateDiff& padding_below,
                                        const ngraph::CoordinateDiff& padding_above,
                                        int groups)
                {
                    if (groups > 1)
                    {
                        // Split one convolution op to N ops where N is the number of groups
                        // and concat results after computation.
                        // reference: https://github.com/NervanaSystems/ngraph-mxnet/blob/fdd692/src/ngraph/ngraph_emitter.cc#L822-L856
                        std::size_t n_data_channels{data->get_shape().at(1)};
                        std::size_t n_filters_channels{filters->get_shape().at(0)};
                        // TODO: ensure n_data_channels % groups = 0
                        std::size_t data_group_size{n_data_channels / groups};
                        std::size_t filters_group_size{n_filters_channels / groups};
                        NodeVector convolution_nodes;

                        // initial bounds for splice
                        std::vector<std::size_t> data_lower_bounds(data->get_shape().size());
                        std::vector<std::size_t> data_upper_bounds{data->get_shape()};
                        std::vector<std::size_t> filters_lower_bounds(filters->get_shape().size());
                        std::vector<std::size_t> filters_upper_bounds{filters->get_shape()};

                        for (std::size_t group{0}; group < groups; ++group)
                        {
                            // slice data
                            data_lower_bounds[1] = group * data_group_size;
                            data_upper_bounds[1] = (group + 1) * data_group_size;
                            auto sliced_data = std::make_shared<ngraph::op::Slice>(
                                data, data_lower_bounds, data_upper_bounds);
                            // slice filters
                            filters_lower_bounds[0] = group * filters_group_size;
                            filters_upper_bounds[0] = (group + 1) * filters_group_size;
                            auto sliced_filters = std::make_shared<ngraph::op::Slice>(
                                filters, filters_lower_bounds, filters_upper_bounds);

                            convolution_nodes.push_back(
                                std::make_shared<ngraph::op::Convolution>(sliced_data,
                                                                          sliced_filters,
                                                                          strides,
                                                                          dilations,
                                                                          padding_below,
                                                                          padding_above));
                        }
                        std::size_t concatenation_axis = 1;
                        return std::make_shared<ngraph::op::Concat>(convolution_nodes,
                                                                    concatenation_axis);
                    }
                    else
                    {
                        return std::make_shared<ngraph::op::Convolution>(
                            data, filters, strides, dilations, padding_below, padding_above);
                    }
                }

            } // namespace

            NodeVector conv(const Node& node)
            {
                const NodeVector& inputs = node.get_ng_inputs();
                auto data = inputs.at(0);
                auto filters = inputs.at(1);

                int64_t groups{node.get_attribute_value<int64_t>("group", 1)};

                // TODO: update to ASSERTION CHECK
                if (groups < 0 || groups > data->get_shape().at(1) ||
                    groups > filters->get_shape().at(0))
                {
                    throw error::parameter::Value{"Conv",
                                                  node.get_name(),
                                                  "incorrect value of 'group' attribute: " +
                                                      std::to_string(groups)};
                }

                auto strides = convpool::get_strides(node);
                auto dilations = convpool::get_dilations(node);
                auto paddings = convpool::get_pads(node);
                const auto& padding_below = paddings.first;
                const auto& padding_above = paddings.second;

                auto conv_node = make_ng_convolution(
                    data, filters, strides, dilations, padding_below, padding_above, groups);

                // no bias param
                if (inputs.size() < 3)
                {
                    return {conv_node};
                }

                auto bias = inputs.at(2);
                const Shape& new_shape = conv_node->get_shape();

                auto broadcasted_bias = std::make_shared<ngraph::op::Broadcast>(
                    bias, new_shape, calculate_broadcast_axes(new_shape, bias->get_shape(), 1));
                return {std::make_shared<ngraph::op::Add>(conv_node, broadcasted_bias)};
            }

        } // namespace op

    } // namespace onnx_import

} // namespace ngraph
<|endoftext|>


<commit_before>/*******************************************************************************
* Copyright 2018 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

#include "ngraph/runtime/cpu/kernel/max_pool.hpp"
#include "ngraph/op/max_pool.hpp"
#include "ngraph/runtime/cpu/cpu_builder.hpp"
#include "ngraph/runtime/cpu/mkldnn_invoke.hpp"
#include "ngraph/runtime/cpu/mkldnn_utils.hpp"

using namespace std;
using namespace ngraph;

namespace ngraph
{
    namespace runtime
    {
        namespace cpu
        {
            template <>
            void Builder::BUILDER_DECL(ngraph::op::MaxPool)
            {
                auto max_pool = static_cast<const ngraph::op::MaxPool*>(node);

                auto& functors = external_function->get_functors();
                auto& tensor_data = external_function->get_tensor_data();

                auto arg0_shape = args[0].get_shape();
                auto out_shape = out[0].get_shape();

                auto& arg0_tensor = tensor_data[args[0].get_name()];
                auto& out_tensor = tensor_data[out[0].get_name()];

                auto window_shape = max_pool->get_window_shape();
                auto window_movement_strides = max_pool->get_window_movement_strides();
                auto padding_below = max_pool->get_padding_below();
                auto padding_above = max_pool->get_padding_above();

                if (runtime::cpu::mkldnn_utils::use_mkldnn_kernel(node))
                {
                    auto& mkldnn_emitter = external_function->get_mkldnn_emitter();
                    auto input_desc = mkldnn_emitter->build_memory_descriptor(
                        args[0], runtime::cpu::mkldnn_utils::get_input_mkldnn_format(node, 0));
                    auto result_desc = mkldnn_emitter->build_memory_descriptor(
                        out[0], runtime::cpu::mkldnn_utils::get_output_mkldnn_format(node, 0));

                    size_t max_pool_index =
                        mkldnn_emitter->build_pooling_forward(mkldnn::algorithm::pooling_max,
                                                              input_desc,
                                                              result_desc,
                                                              window_movement_strides,
                                                              window_shape,
                                                              padding_below,
                                                              padding_above);

                    auto& deps = mkldnn_emitter->get_primitive_deps(max_pool_index);

                    auto functor = [&, max_pool_index](CPURuntimeContext* ctx) {
                        cpu::mkldnn_utils::set_memory_ptr(ctx, deps[0], arg0_tensor);
                        cpu::mkldnn_utils::set_memory_ptr(ctx, deps[1], out_tensor);
                        cpu::mkldnn_utils::mkldnn_invoke_primitive(ctx, max_pool_index);
                    };
                    functors.emplace_back(functor);
                }
                else
                {
                    std::function<decltype(runtime::cpu::kernel::max_pool<float>)> kernel;

                    SELECT_KERNEL(
                        kernel, out[0].get_element_type(), runtime::cpu::kernel::max_pool);

                    auto functor = [&,
                                    kernel,
                                    arg0_shape,
                                    out_shape,
                                    window_shape,
                                    window_movement_strides,
                                    padding_below,
                                    padding_above](CPURuntimeContext* ctx) {
                        kernel(arg0_tensor,
                               out_tensor,
                               arg0_shape,
                               out_shape,
                               window_shape,
                               window_movement_strides,
                               padding_below,
                               padding_above);
                    };
                    functors.emplace_back(functor);
                }
            }

            REGISTER_OP_BUILDER(MaxPool);
        }
    }
}
<commit_msg>DEX MaxPoolWithIndices (#1299)<commit_after>/*******************************************************************************
* Copyright 2018 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

#include "ngraph/runtime/cpu/kernel/max_pool.hpp"
#include "ngraph/op/max_pool.hpp"
#include "ngraph/runtime/cpu/cpu_builder.hpp"
#include "ngraph/runtime/cpu/mkldnn_invoke.hpp"
#include "ngraph/runtime/cpu/mkldnn_utils.hpp"
#include "ngraph/runtime/cpu/op/max_pool_with_indices.hpp"

using namespace std;
using namespace ngraph;

namespace ngraph
{
    namespace runtime
    {
        namespace cpu
        {
            template <>
            void Builder::BUILDER_DECL(ngraph::op::MaxPool)
            {
                auto max_pool = static_cast<const ngraph::op::MaxPool*>(node);

                auto& functors = external_function->get_functors();
                auto& tensor_data = external_function->get_tensor_data();

                auto arg0_shape = args[0].get_shape();
                auto out_shape = out[0].get_shape();

                auto& arg0_tensor = tensor_data[args[0].get_name()];
                auto& out_tensor = tensor_data[out[0].get_name()];

                auto window_shape = max_pool->get_window_shape();
                auto window_movement_strides = max_pool->get_window_movement_strides();
                auto padding_below = max_pool->get_padding_below();
                auto padding_above = max_pool->get_padding_above();

                if (runtime::cpu::mkldnn_utils::use_mkldnn_kernel(node))
                {
                    auto& mkldnn_emitter = external_function->get_mkldnn_emitter();
                    auto input_desc = mkldnn_emitter->build_memory_descriptor(
                        args[0], runtime::cpu::mkldnn_utils::get_input_mkldnn_format(node, 0));
                    auto result_desc = mkldnn_emitter->build_memory_descriptor(
                        out[0], runtime::cpu::mkldnn_utils::get_output_mkldnn_format(node, 0));

                    size_t max_pool_index =
                        mkldnn_emitter->build_pooling_forward(mkldnn::algorithm::pooling_max,
                                                              input_desc,
                                                              result_desc,
                                                              window_movement_strides,
                                                              window_shape,
                                                              padding_below,
                                                              padding_above);

                    auto& deps = mkldnn_emitter->get_primitive_deps(max_pool_index);

                    auto functor = [&, max_pool_index](CPURuntimeContext* ctx) {
                        cpu::mkldnn_utils::set_memory_ptr(ctx, deps[0], arg0_tensor);
                        cpu::mkldnn_utils::set_memory_ptr(ctx, deps[1], out_tensor);
                        cpu::mkldnn_utils::mkldnn_invoke_primitive(ctx, max_pool_index);
                    };
                    functors.emplace_back(functor);
                }
                else
                {
                    std::function<decltype(runtime::cpu::kernel::max_pool<float>)> kernel;

                    SELECT_KERNEL(
                        kernel, out[0].get_element_type(), runtime::cpu::kernel::max_pool);

                    auto functor = [&,
                                    kernel,
                                    arg0_shape,
                                    out_shape,
                                    window_shape,
                                    window_movement_strides,
                                    padding_below,
                                    padding_above](CPURuntimeContext* ctx) {
                        kernel(arg0_tensor,
                               out_tensor,
                               arg0_shape,
                               out_shape,
                               window_shape,
                               window_movement_strides,
                               padding_below,
                               padding_above);
                    };
                    functors.emplace_back(functor);
                }
            }

            template <>
            void Builder::BUILDER_DECL(ngraph::op::MaxPoolWithIndices)
            {
                if (!runtime::cpu::mkldnn_utils::use_mkldnn_kernel(node))
                {
                    throw ngraph_error("MaxPoolWithIndices isn't supported");
                }

                auto max_pool = static_cast<const ngraph::op::MaxPoolWithIndices*>(node);

                auto& functors = external_function->get_functors();
                auto& tensor_data = external_function->get_tensor_data();

                auto& arg0_tensor = tensor_data[args[0].get_name()];
                auto& out0_tensor = tensor_data[out[0].get_name()];
                auto& out1_tensor = tensor_data[out[1].get_name()];

                auto& mkldnn_emitter = external_function->get_mkldnn_emitter();
                auto input_desc = mkldnn_emitter->build_memory_descriptor(
                    args[0], runtime::cpu::mkldnn_utils::get_input_mkldnn_format(node, 0));
                auto result_desc = mkldnn_emitter->build_memory_descriptor(
                    out[0], runtime::cpu::mkldnn_utils::get_output_mkldnn_format(node, 0));

                size_t max_pool_index = mkldnn_emitter->build_max_pooling_with_indices_forward(
                    mkldnn::algorithm::pooling_max,
                    input_desc,
                    result_desc,
                    max_pool->get_window_movement_strides(),
                    max_pool->get_window_shape(),
                    max_pool->get_padding_below(),
                    max_pool->get_padding_above());

                auto& deps = mkldnn_emitter->get_primitive_deps(max_pool_index);

                auto functor = [&, max_pool_index](CPURuntimeContext* ctx) {
                    cpu::mkldnn_utils::set_memory_ptr(ctx, deps[0], arg0_tensor);
                    cpu::mkldnn_utils::set_memory_ptr(ctx, deps[1], out0_tensor);
                    cpu::mkldnn_utils::set_memory_ptr(ctx, deps[2], out1_tensor);
                    cpu::mkldnn_utils::mkldnn_invoke_primitive(ctx, max_pool_index);
                };
                functors.emplace_back(functor);
            }

            template <>
            void Builder::BUILDER_DECL(ngraph::op::MaxPoolWithIndicesBackprop)
            {
                if (!runtime::cpu::mkldnn_utils::use_mkldnn_kernel(node))
                {
                    throw ngraph_error("MaxPoolWithIndicesBackprop isn't supported");
                }

                auto& functors = external_function->get_functors();
                auto& tensor_data = external_function->get_tensor_data();

                auto& arg1_tensor = tensor_data[args[1].get_name()];
                auto& arg2_tensor = tensor_data[args[2].get_name()];
                auto& out_tensor = tensor_data[out[0].get_name()];

                auto mpb = static_cast<const ngraph::op::MaxPoolWithIndicesBackprop*>(node);

                auto& mkldnn_emitter = external_function->get_mkldnn_emitter();
                auto diff_dst_desc = mkldnn_emitter->build_memory_descriptor(
                    args[1], runtime::cpu::mkldnn_utils::get_input_mkldnn_format(node, 1));
                auto diff_src_desc = mkldnn_emitter->build_memory_descriptor(
                    out[0], runtime::cpu::mkldnn_utils::get_output_mkldnn_format(node, 0));

                size_t max_pool_index = mkldnn_emitter->build_max_pooling_with_indices_backward(
                    mkldnn::algorithm::pooling_max,
                    diff_dst_desc,
                    diff_src_desc,
                    mpb->get_window_movement_strides(),
                    mpb->get_window_shape(),
                    mpb->get_padding_below(),
                    mpb->get_padding_above());

                auto& deps = mkldnn_emitter->get_primitive_deps(max_pool_index);

                auto functor = [&, max_pool_index](CPURuntimeContext* ctx) {
                    cpu::mkldnn_utils::set_memory_ptr(ctx, deps[0], arg1_tensor);
                    cpu::mkldnn_utils::set_memory_ptr(ctx, deps[1], arg2_tensor);
                    cpu::mkldnn_utils::set_memory_ptr(ctx, deps[2], out_tensor);
                    cpu::mkldnn_utils::mkldnn_invoke_primitive(ctx, max_pool_index);
                };
                functors.emplace_back(functor);
            }

            REGISTER_OP_BUILDER(MaxPool);
            REGISTER_OP_BUILDER(MaxPoolWithIndices);
            REGISTER_OP_BUILDER(MaxPoolWithIndicesBackprop);
        }
    }
}
<|endoftext|>


<commit_before>/*=========================================================================

Program:   BlueBerry Platform
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "berryProvisioningInfo.h"

#include <berryLog.h>

#include <QFile>
#include <QFileInfo>
#include <QTextStream>
#include <QCoreApplication>

namespace berry {

#ifdef CMAKE_INTDIR
const QString ProvisioningInfo::intermediateOutDir = QString(CMAKE_INTDIR);
#else
const QString ProvisioningInfo::intermediateOutDir = QString();
#endif

ProvisioningInfo::ProvisioningInfo(const QString& file)
{
  this->readProvisioningFile(file);
}

QStringList ProvisioningInfo::getPluginDirs() const
{
  return pluginDirs.toList();
}

QList<QUrl> ProvisioningInfo::getPluginsToInstall() const
{
  return pluginsToInstall;
}

QList<QUrl> ProvisioningInfo::getPluginsToStart() const
{
  return pluginsToStart;
}

void ProvisioningInfo::readProvisioningFile(const QString& filePath)
{
  QFile file(filePath);
  file.open(QFile::ReadOnly);
  QTextStream fileStream(&file);
  QRegExp sep("\\s+");
  QString line;
  int count = 1;
  do {
    line = fileStream.readLine().trimmed();
    if (!line.isEmpty() && !line.startsWith('#'))
    {
      QString keyword = line.section(sep, 0, 0);
      QString value = line.mid(keyword.size()).trimmed();
      value = substituteKeywords(value);

      if (keyword.isEmpty())
      {
        BERRY_WARN << "Keyword missing in line " << count
                   << " of provisioning file " << filePath.toStdString();
        continue;
      }

      Keyword key = UNKNOWN;
      if (keyword.compare("READ", Qt::CaseInsensitive) == 0)
      {
        key = READ;
      }
      else if (keyword.compare("INSTALL", Qt::CaseInsensitive) == 0)
      {
        key = INSTALL;
      }
      else if (keyword.compare("START", Qt::CaseInsensitive) == 0)
      {
        key = START;
      }
      else if (keyword.compare("STOP", Qt::CaseInsensitive) == 0)
      {
        key = STOP;
      }

      if (key == UNKNOWN)
      {
        BERRY_WARN << "Keyword " << keyword.toStdString() << " in line "
                      << count << " of provisioning file "
                      << filePath.toStdString() << " unknown";
        continue;
      }

      if (value.isEmpty())
      {
        BERRY_WARN << "Value after keyword " << keyword.toStdString()
                  << " missing in line " << count
                  << " of provisioning file " << filePath.toStdString();
        continue;
      }

      switch (key)
      {
      case READ:
      {
        QUrl readFileUrl(value);
        if (!readFileUrl.isValid())
        {
          BERRY_WARN << "The READ URL " << value.toStdString()
                     << "is invalid: " << readFileUrl.errorString().toStdString();
          break;
        }
        this->readProvisioningFile(readFileUrl.toLocalFile());
        break;
      }
      case INSTALL:
      {
        this->addPluginToInstall(value);
        break;
      }
      case START:
      {
        this->addPluginToStart(value);
        break;
      }
      case STOP:
      {
        break;
      }
      }
    }
    ++count;
  } while (!line.isNull());
}

QUrl ProvisioningInfo::addPluginToInstall(const QString& file)
{
  QUrl pluginUrl(file);
  if (!pluginUrl.isValid())
  {
    BERRY_WARN << "The plugin URL " << file.toStdString() << " is invalid:"
               << pluginUrl.errorString().toStdString();
    return QUrl();
  }

  QFileInfo fileInfo(pluginUrl.toLocalFile());
  if (!fileInfo.exists())
  {
    QString fileName = fileInfo.fileName();
    QString filePath = fileInfo.absolutePath();
    if (!intermediateOutDir.isEmpty())
    {
      // search in the intermediate output dir
      QString filePath2 = filePath + "/" + intermediateOutDir;
      fileInfo = QFileInfo(filePath2 + "/" + fileName);
      if (!fileInfo.exists())
      {
        BERRY_WARN << "The plugin " << fileName.toStdString() << " was not found in "
                   << filePath.toStdString() << " or " << filePath2.toStdString();
        return QUrl();
      }
      pluginUrl = QUrl::fromLocalFile(fileInfo.canonicalFilePath());
      pluginDirs.insert(fileInfo.canonicalPath());
    }
    else
    {
      BERRY_WARN << "The plugin " << fileName.toStdString() << " was not found in "
                 << filePath.toStdString();
      return QUrl();
    }
  }
  else
  {
    pluginDirs.insert(fileInfo.canonicalPath());
  }

  pluginsToInstall.append(pluginUrl);
  return pluginUrl;
}

void ProvisioningInfo::addPluginToStart(const QString& file)
{
  QUrl pluginUrl = this->addPluginToInstall(file);
  if (!pluginUrl.isEmpty())
  {
    pluginsToStart.append(pluginUrl);
  }
}

QString ProvisioningInfo::substituteKeywords(const QString& value) const
{
  QString appPath = QCoreApplication::applicationDirPath();
  if (appPath.endsWith('/'))
  {
    appPath.chop(1);
  }

#ifdef CMAKE_INTDIR
  // Strip the intermediate dir from the application path
  QString intDir(CMAKE_INTDIR);
  appPath.chop(intDir.size()+1);
#endif

  return QString(value).replace("@EXECUTABLE_DIR", appPath, Qt::CaseInsensitive);
}

}
<commit_msg>Fix some issues when starting BlueBerry apps in an install tree.<commit_after>/*=========================================================================

Program:   BlueBerry Platform
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "berryProvisioningInfo.h"

#include <berryLog.h>

#include <QFile>
#include <QFileInfo>
#include <QTextStream>
#include <QCoreApplication>

namespace berry {

#ifdef CMAKE_INTDIR
const QString ProvisioningInfo::intermediateOutDir = QString(CMAKE_INTDIR);
#else
const QString ProvisioningInfo::intermediateOutDir = QString();
#endif

ProvisioningInfo::ProvisioningInfo(const QString& file)
{
  this->readProvisioningFile(file);
}

QStringList ProvisioningInfo::getPluginDirs() const
{
  return pluginDirs.toList();
}

QList<QUrl> ProvisioningInfo::getPluginsToInstall() const
{
  return pluginsToInstall;
}

QList<QUrl> ProvisioningInfo::getPluginsToStart() const
{
  return pluginsToStart;
}

void ProvisioningInfo::readProvisioningFile(const QString& filePath)
{
  QFile file(filePath);
  file.open(QFile::ReadOnly);
  QTextStream fileStream(&file);
  QRegExp sep("\\s+");
  QString line;
  int count = 1;
  do {
    line = fileStream.readLine().trimmed();
    if (!line.isEmpty() && !line.startsWith('#'))
    {
      QString keyword = line.section(sep, 0, 0);
      QString value = line.mid(keyword.size()).trimmed();
      value = substituteKeywords(value);

      if (keyword.isEmpty())
      {
        BERRY_WARN << "Keyword missing in line " << count
                   << " of provisioning file " << filePath.toStdString();
        continue;
      }

      Keyword key = UNKNOWN;
      if (keyword.compare("READ", Qt::CaseInsensitive) == 0)
      {
        key = READ;
      }
      else if (keyword.compare("INSTALL", Qt::CaseInsensitive) == 0)
      {
        key = INSTALL;
      }
      else if (keyword.compare("START", Qt::CaseInsensitive) == 0)
      {
        key = START;
      }
      else if (keyword.compare("STOP", Qt::CaseInsensitive) == 0)
      {
        key = STOP;
      }

      if (key == UNKNOWN)
      {
        BERRY_WARN << "Keyword " << keyword.toStdString() << " in line "
                      << count << " of provisioning file "
                      << filePath.toStdString() << " unknown";
        continue;
      }

      if (value.isEmpty())
      {
        BERRY_WARN << "Value after keyword " << keyword.toStdString()
                  << " missing in line " << count
                  << " of provisioning file " << filePath.toStdString();
        continue;
      }

      switch (key)
      {
      case READ:
      {
        QUrl readFileUrl(value);
        if (!readFileUrl.isValid())
        {
          BERRY_WARN << "The READ URL " << value.toStdString()
                     << "is invalid: " << readFileUrl.errorString().toStdString();
          break;
        }
        this->readProvisioningFile(readFileUrl.toLocalFile());
        break;
      }
      case INSTALL:
      {
        this->addPluginToInstall(value);
        break;
      }
      case START:
      {
        this->addPluginToStart(value);
        break;
      }
      case STOP:
      {
        break;
      }
      }
    }
    ++count;
  } while (!line.isNull());
}

QUrl ProvisioningInfo::addPluginToInstall(const QString& file)
{
  QUrl pluginUrl(file);
  if (!pluginUrl.isValid())
  {
    BERRY_WARN << "The plugin URL " << file.toStdString() << " is invalid:"
               << pluginUrl.errorString().toStdString();
    return QUrl();
  }

  QFileInfo fileInfo(pluginUrl.toLocalFile());
  if (!fileInfo.exists())
  {
    QString fileName = fileInfo.fileName();
    QString filePath = fileInfo.absolutePath();
    if (!intermediateOutDir.isEmpty())
    {
      // search in the intermediate output dir
      QString filePath2 = filePath + "/" + intermediateOutDir;
      fileInfo = QFileInfo(filePath2 + "/" + fileName);
      if (!fileInfo.exists())
      {
        BERRY_WARN << "The plugin " << fileName.toStdString() << " was not found in "
                   << filePath.toStdString() << " or " << filePath2.toStdString();
        return QUrl();
      }
      pluginUrl = QUrl::fromLocalFile(fileInfo.canonicalFilePath());
      pluginDirs.insert(fileInfo.canonicalPath());
    }
    else
    {
      BERRY_WARN << "The plugin " << fileName.toStdString() << " was not found in "
                 << filePath.toStdString();
      return QUrl();
    }
  }
  else
  {
    pluginDirs.insert(fileInfo.canonicalPath());
  }

  pluginsToInstall.append(pluginUrl);
  return pluginUrl;
}

void ProvisioningInfo::addPluginToStart(const QString& file)
{
  QUrl pluginUrl = this->addPluginToInstall(file);
  if (!pluginUrl.isEmpty())
  {
    pluginsToStart.append(pluginUrl);
  }
}

QString ProvisioningInfo::substituteKeywords(const QString& value) const
{
  QString appPath = QCoreApplication::applicationDirPath();
  if (appPath.endsWith('/'))
  {
    appPath.chop(1);
  }

#ifdef CMAKE_INTDIR
  // Strip the intermediate dir from the application path
  QString intDir(CMAKE_INTDIR);
  if (appPath.endsWith(intDir))
  {
    appPath.chop(intDir.size()+1);
  }
#endif

#ifdef _WIN32
  if (value.contains("@EXECUTABLE_DIR") && value.contains("blueberry_osgi"))
  {
    // special case for org_blueberry_osgi in install trees for Windows
    return QString(value).replace("@EXECUTABLE_DIR", appPath, Qt::CaseInsensitive).replace("plugins/", "");
  }
#endif

  return QString(value).replace("@EXECUTABLE_DIR", appPath, Qt::CaseInsensitive);
}

}
<|endoftext|>


<commit_before>/*-
 * Copyright (c) 2014 Peter Tworek
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 2. Redistributions 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.
 * 3. Neither the name of the author nor the names of any co-contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
 */

#include "YTWebFontLoader.h"

#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QStandardPaths>
#include <QNetworkReply>
#include <QFontDatabase>
#include <QFile>
#include <QDebug>

static QUrl kYouTubeWebFontURL = QUrl("https://www.youtube.com/s/tv/fonts/youtube-icons.ttf");

extern QSharedPointer<QNetworkAccessManager> GetNetworkAccessManager();

YTWebFontLoader::YTWebFontLoader(QObject *parent)
    : QObject(parent)
    , _loaded(false)
    , _network_access_manager(GetNetworkAccessManager())
{
    _fontPath = QStandardPaths::writableLocation(
        QStandardPaths::DataLocation).append("/youtube-icons.ttf");
}

YTWebFontLoader::~YTWebFontLoader()
{
}

void
YTWebFontLoader::load()
{
    QNetworkRequest request(kYouTubeWebFontURL);
    if (QFile::exists(_fontPath) && installFont()) {
        return;
    }
    _reply = _network_access_manager->get(request);
    connect(_reply, SIGNAL(finished()), this, SLOT(onFinished()));
}

bool
YTWebFontLoader::installFont()
{
    if (QFontDatabase::addApplicationFont(_fontPath) < 0) {
        qCritical() << "Failed to install YouTube web font";
        return false;
    }
    _loaded = true;
    emit loadedChanged(true);
    return true;
}

void
YTWebFontLoader::onFinished()
{
    QFile fontFile(_fontPath);

    if (fontFile.open(QIODevice::WriteOnly)) {
        if (_reply->error() == QNetworkReply::NoError) {
            fontFile.write(_reply->readAll());
            fontFile.close();
            installFont();
        } else {
            qCritical() << "Failed to download font file, error: " << _reply->error();
            emit error();
        }
    } else {
        qCritical() << "Failed to open font file for writing: " << _fontPath;
        emit error();
    }

    _reply->deleteLater();
    _reply = NULL;
}
<commit_msg>YTWebFontLoader: Make sure the font is not loaded twice.<commit_after>/*-
 * Copyright (c) 2014 Peter Tworek
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 2. Redistributions 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.
 * 3. Neither the name of the author nor the names of any co-contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
 */

#include "YTWebFontLoader.h"

#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QStandardPaths>
#include <QNetworkReply>
#include <QFontDatabase>
#include <QFile>
#include <QDebug>

static QUrl kYouTubeWebFontURL = QUrl("https://www.youtube.com/s/tv/fonts/youtube-icons.ttf");

extern QSharedPointer<QNetworkAccessManager> GetNetworkAccessManager();

YTWebFontLoader::YTWebFontLoader(QObject *parent)
    : QObject(parent)
    , _loaded(false)
    , _network_access_manager(GetNetworkAccessManager())
{
    _fontPath = QStandardPaths::writableLocation(
        QStandardPaths::DataLocation).append("/youtube-icons.ttf");
}

YTWebFontLoader::~YTWebFontLoader()
{
}

void
YTWebFontLoader::load()
{
    if (_loaded) {
        return;
    }

    if (QFile::exists(_fontPath) && installFont()) {
        return;
    }

    QNetworkRequest request(kYouTubeWebFontURL);
    _reply = _network_access_manager->get(request);
    connect(_reply, SIGNAL(finished()), this, SLOT(onFinished()));
}

bool
YTWebFontLoader::installFont()
{
    if (QFontDatabase::addApplicationFont(_fontPath) < 0) {
        qCritical() << "Failed to install YouTube web font";
        return false;
    }
    _loaded = true;
    emit loadedChanged(true);
    return true;
}

void
YTWebFontLoader::onFinished()
{
    QFile fontFile(_fontPath);

    if (fontFile.open(QIODevice::WriteOnly)) {
        if (_reply->error() == QNetworkReply::NoError) {
            fontFile.write(_reply->readAll());
            fontFile.close();
            installFont();
        } else {
            qCritical() << "Failed to download font file, error: " << _reply->error();
            emit error();
        }
    } else {
        qCritical() << "Failed to open font file for writing: " << _fontPath;
        emit error();
    }

    _reply->deleteLater();
    _reply = NULL;
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file.  Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/

#include "helloworldplugin.h"

#include <coreplugin/actionmanager/actionmanagerinterface.h>
#include <coreplugin/basemode.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/uniqueidmanager.h>
#include <extensionsystem/pluginmanager.h>

#include <QtCore/QDebug>
#include <QtCore/QtPlugin>
#include <QtGui/QAction>
#include <QtGui/QMenu>
#include <QtGui/QMessageBox>
#include <QtGui/QPushButton>

using namespace HelloWorld::Internal;

/*! Constructs the Hello World plugin. Normally plugins don't do anything in
    their constructor except for initializing their member variables. The
    actual work is done later, in the initialize() and extensionsInitialized()
    methods.
*/
HelloWorldPlugin::HelloWorldPlugin()
{
}

/*! Plugins are responsible for deleting objects they created on the heap, and
    to unregister objects from the plugin manager that they registered there.
*/
HelloWorldPlugin::~HelloWorldPlugin()
{
}

/*! Initializes the plugin. Returns true on success.
    Plugins want to register objects with the plugin manager here.

    \a error_message can be used to pass an error message to the plugin system,
       if there was any.
*/
bool HelloWorldPlugin::initialize(const QStringList &arguments, QString *error_message)
{
    Q_UNUSED(arguments)
    Q_UNUSED(error_message)

    // Get the primary access point to the workbench.
    Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();

    // Create a unique context id for our own view, that will be used for the
    // menu entry later.
    QList<int> context = QList<int>()
        << core->uniqueIDManager()->uniqueIdentifier(
                QLatin1String("HelloWorld.MainView"));

    // Create an action to be triggered by a menu entry
    QAction *helloWorldAction = new QAction("Say \"&Hello World!\"", this);
    connect(helloWorldAction, SIGNAL(triggered()), SLOT(sayHelloWorld()));

    // Register the action with the action manager
    Core::ActionManager *actionManager = core->actionManager();
    Core::Command *command =
            actionManager->registerAction(
                    helloWorldAction, "HelloWorld.HelloWorldAction", context);

    // Create our own menu to place in the Tools menu
    Core::ActionContainer *helloWorldMenu =
            actionManager->createMenu("HelloWorld.HelloWorldMenu");
    QMenu *menu = helloWorldMenu->menu();
    menu->setTitle(tr("&Hello World"));
    menu->setEnabled(true);

    // Add the Hello World action command to the menu
    helloWorldMenu->addAction(command);

    // Request the Tools menu and add the Hello World menu to it
    Core::IActionContainer *toolsMenu =
            actionManager->actionContainer(Core::Constants::M_TOOLS);
    toolsMenu->addMenu(helloWorldMenu);

    // Add a mode with a push button based on BaseMode. Like the BaseView,
    // it will unregister itself from the plugin manager when it is deleted.
    Core::BaseMode *baseMode = new Core::BaseMode;
    baseMode->setUniqueModeName("HelloWorld.HelloWorldMode");
    baseMode->setName(tr("Hello world!"));
    baseMode->setIcon(QIcon());
    baseMode->setPriority(0);
    baseMode->setWidget(new QPushButton(tr("Hello World PushButton!")));
    addAutoReleasedObject(baseMode);

    // Add the Hello World action command to the mode manager (with 0 priority)
    Core::ModeManager *modeManager = core->modeManager();
    modeManager->addAction(command, 0);

    return true;
}

/*! Notification that all extensions that this plugin depends on have been
    initialized. The dependencies are defined in the plugins .qwp file.

    Normally this method is used for things that rely on other plugins to have
    added objects to the plugin manager, that implement interfaces that we're
    interested in. These objects can now be requested through the
    PluginManagerInterface.

    The HelloWorldPlugin doesn't need things from other plugins, so it does
    nothing here.
*/
void HelloWorldPlugin::extensionsInitialized()
{
}

void HelloWorldPlugin::sayHelloWorld()
{
    // When passing 0 for the parent, the message box becomes an
    // application-global modal dialog box
    QMessageBox::information(
            0, "Hello World!", "Hello World! Beautiful day today, isn't it?");
}

Q_EXPORT_PLUGIN(HelloWorldPlugin)
<commit_msg>Fixes:    - HelloWorld compilation<commit_after>/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file.  Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/

#include "helloworldplugin.h"

#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/basemode.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/uniqueidmanager.h>
#include <extensionsystem/pluginmanager.h>

#include <QtCore/QDebug>
#include <QtCore/QtPlugin>
#include <QtGui/QAction>
#include <QtGui/QMenu>
#include <QtGui/QMessageBox>
#include <QtGui/QPushButton>

using namespace HelloWorld::Internal;

/*! Constructs the Hello World plugin. Normally plugins don't do anything in
    their constructor except for initializing their member variables. The
    actual work is done later, in the initialize() and extensionsInitialized()
    methods.
*/
HelloWorldPlugin::HelloWorldPlugin()
{
}

/*! Plugins are responsible for deleting objects they created on the heap, and
    to unregister objects from the plugin manager that they registered there.
*/
HelloWorldPlugin::~HelloWorldPlugin()
{
}

/*! Initializes the plugin. Returns true on success.
    Plugins want to register objects with the plugin manager here.

    \a error_message can be used to pass an error message to the plugin system,
       if there was any.
*/
bool HelloWorldPlugin::initialize(const QStringList &arguments, QString *error_message)
{
    Q_UNUSED(arguments)
    Q_UNUSED(error_message)

    // Get the primary access point to the workbench.
    Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();

    // Create a unique context id for our own view, that will be used for the
    // menu entry later.
    QList<int> context = QList<int>()
        << core->uniqueIDManager()->uniqueIdentifier(
                QLatin1String("HelloWorld.MainView"));

    // Create an action to be triggered by a menu entry
    QAction *helloWorldAction = new QAction("Say \"&Hello World!\"", this);
    connect(helloWorldAction, SIGNAL(triggered()), SLOT(sayHelloWorld()));

    // Register the action with the action manager
    Core::ActionManager *actionManager = core->actionManager();
    Core::Command *command =
            actionManager->registerAction(
                    helloWorldAction, "HelloWorld.HelloWorldAction", context);

    // Create our own menu to place in the Tools menu
    Core::ActionContainer *helloWorldMenu =
            actionManager->createMenu("HelloWorld.HelloWorldMenu");
    QMenu *menu = helloWorldMenu->menu();
    menu->setTitle(tr("&Hello World"));
    menu->setEnabled(true);

    // Add the Hello World action command to the menu
    helloWorldMenu->addAction(command);

    // Request the Tools menu and add the Hello World menu to it
    Core::ActionContainer *toolsMenu =
            actionManager->actionContainer(Core::Constants::M_TOOLS);
    toolsMenu->addMenu(helloWorldMenu);

    // Add a mode with a push button based on BaseMode. Like the BaseView,
    // it will unregister itself from the plugin manager when it is deleted.
    Core::BaseMode *baseMode = new Core::BaseMode;
    baseMode->setUniqueModeName("HelloWorld.HelloWorldMode");
    baseMode->setName(tr("Hello world!"));
    baseMode->setIcon(QIcon());
    baseMode->setPriority(0);
    baseMode->setWidget(new QPushButton(tr("Hello World PushButton!")));
    addAutoReleasedObject(baseMode);

    // Add the Hello World action command to the mode manager (with 0 priority)
    Core::ModeManager *modeManager = core->modeManager();
    modeManager->addAction(command, 0);

    return true;
}

/*! Notification that all extensions that this plugin depends on have been
    initialized. The dependencies are defined in the plugins .qwp file.

    Normally this method is used for things that rely on other plugins to have
    added objects to the plugin manager, that implement interfaces that we're
    interested in. These objects can now be requested through the
    PluginManagerInterface.

    The HelloWorldPlugin doesn't need things from other plugins, so it does
    nothing here.
*/
void HelloWorldPlugin::extensionsInitialized()
{
}

void HelloWorldPlugin::sayHelloWorld()
{
    // When passing 0 for the parent, the message box becomes an
    // application-global modal dialog box
    QMessageBox::information(
            0, "Hello World!", "Hello World! Beautiful day today, isn't it?");
}

Q_EXPORT_PLUGIN(HelloWorldPlugin)
<|endoftext|>