<commit_before>#include <ctrcommon/input.hpp>
#include <ctrcommon/platform.hpp>
#include <ctrcommon/ui.hpp>

#include <stdio.h>

#include <sstream>
#include <iomanip>

#include <sys/dirent.h>
#include <3ds.h>
#include <ctrcommon/app.hpp>

typedef enum {
    INSTALL_CIA,
    DELETE_CIA,
    DELETE_TITLE,
    LAUNCH_TITLE
} Mode;

int main(int argc, char **argv) {
    if(!platformInit()) {
        return 0;
    }

    bool ninjhax = platformIsNinjhax();

    std::vector<std::string> extensions;
    extensions.push_back("cia");

    MediaType destination = SD;
    Mode mode = INSTALL_CIA;
    bool exit = false;
    bool netInstall = false;
    u64 freeSpace = fsGetFreeSpace(destination);
    auto onLoop = [&]() {
        if(ninjhax && inputIsPressed(BUTTON_START)) {
            exit = true;
            return true;
        }

        bool breakLoop = false;

        if(inputIsPressed(BUTTON_L)) {
            if(destination == SD) {
                destination = NAND;
            } else {
                destination = SD;
            }

            freeSpace = fsGetFreeSpace(destination);
            if(mode == DELETE_TITLE) {
                breakLoop = true;
            }
        }

        if(inputIsPressed(BUTTON_R)) {
            if(mode == INSTALL_CIA) {
                mode = DELETE_CIA;
            } else if(mode == DELETE_CIA) {
                mode = DELETE_TITLE;
                breakLoop = true;
            } else if(mode == DELETE_TITLE) {
                mode = LAUNCH_TITLE;
            } else if(mode == LAUNCH_TITLE) {
                mode = INSTALL_CIA;
                breakLoop = true;
            }
        }

        if(inputIsPressed(BUTTON_Y)) {
            netInstall = true;
            breakLoop = true;
        }

        std::stringstream stream;
        stream << "Free Space: " << freeSpace << " bytes (" << std::fixed << std::setprecision(2) << freeSpace / 1024.0f / 1024.0f << "MB)" << "\n";
        stream << "Destination: " << (destination == NAND ? "NAND" : "SD") << ", Mode: " << (mode == INSTALL_CIA ? "Install CIA" : mode == DELETE_CIA ? "Delete CIA" : mode == DELETE_TITLE ? "Delete Title" : "Launch Title") << "\n";
        stream << "L - Switch Destination, R - Switch Mode" << "\n";
        if(mode == INSTALL_CIA) {
            stream << "X - Install all CIAs in the current directory" << "\n";
        } else if(mode == DELETE_CIA) {
            stream << "X - Delete all CIAs in the current directory" << "\n";
        }

        stream << "Y - Receive an app over the network" << "\n";
        if(ninjhax) {
            stream << "START - Exit to launcher" << "\n";
        }

        std::string str = stream.str();
        screenDrawString(str, (screenGetWidth() - screenGetStrWidth(str)) / 2, screenGetHeight() - 4 - screenGetStrHeight(str), 255, 255, 255);

        return breakLoop;
    };

    auto onProgress = [&](u64 pos, u64 totalSize) {
        std::stringstream details;
        details << "(" << std::fixed << std::setprecision(2) << ((double) pos / 1024.0 / 1024.0) << "MB / " << std::fixed << std::setprecision(2) << ((double) totalSize / 1024.0 / 1024.0) << "MB)" << "\n";
        details << "Press B to cancel.";

        u32 progress = (u32) (((double) pos / (double) totalSize) * 100);
        uiDisplayProgress(TOP_SCREEN, "Installing", details.str(), true, progress);
        inputPoll();
        return !inputIsPressed(BUTTON_B);
    };

    while(platformIsRunning()) {
        std::string fileTarget;
        App appTarget;
        if(mode == INSTALL_CIA || mode == DELETE_CIA) {
            uiSelectFile(&fileTarget, "/", extensions, [&](const std::string currDirectory, bool inRoot, bool &updateList) {
                if(inputIsPressed(BUTTON_X)) {
                    std::stringstream confirmMsg;
                    if(mode == INSTALL_CIA) {
                        confirmMsg << "Install ";
                    } else {
                        confirmMsg << "Delete ";
                    }

                    confirmMsg << "all CIAs in the current directory?";
                    if(uiPrompt(TOP_SCREEN, confirmMsg.str(), true)) {
                        bool failed = false;
                        std::vector<FileInfo> contents = fsGetDirectoryContents(currDirectory);
                        for(std::vector<FileInfo>::iterator it = contents.begin(); it != contents.end(); it++) {
                            std::string path = (*it).path;
                            std::string fileName = (*it).name;
                            if(!fsIsDirectory(path) && fsHasExtensions(path, extensions)) {
                                if(mode == INSTALL_CIA) {
                                    AppResult ret = appInstallFile(destination, path, onProgress);
                                    if(ret != APP_SUCCESS) {
                                        std::stringstream resultMsg;
                                        resultMsg << "Install failed!" << "\n";
                                        resultMsg << fileName << "\n";
                                        resultMsg << appGetResultString(ret) << "\n";
                                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                                        failed = true;
                                        break;
                                    }
                                } else {
                                    if(!fsDelete(path)) {
                                        std::stringstream resultMsg;
                                        resultMsg << "Delete failed!" << "\n";
                                        resultMsg << fileName << "\n";
                                        resultMsg << platformGetErrorString(platformGetError()) << "\n";
                                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                                        failed = true;
                                        break;
                                    } else {
                                        updateList = true;
                                    }
                                }
                            }
                        }

                        if(!failed) {
                            uiPrompt(TOP_SCREEN, "Install succeeded!\n", false);
                        }

                        freeSpace = fsGetFreeSpace(destination);
                    }
                }

                return onLoop();
            }, [&](const std::string path, bool &updateList) {
                std::stringstream confirmMsg;
                if(mode == INSTALL_CIA) {
                    confirmMsg << "Install ";
                } else {
                    confirmMsg << "Delete ";
                }

                confirmMsg << "the selected CIA?";
                if(uiPrompt(TOP_SCREEN, confirmMsg.str(), true)) {
                    std::stringstream resultMsg;
                    if(mode == INSTALL_CIA) {
                        resultMsg << "Install ";
                    } else {
                        resultMsg << "Delete ";
                    }

                    if(mode == INSTALL_CIA) {
                        AppResult ret = appInstallFile(destination, path, onProgress);
                        if(ret == APP_SUCCESS) {
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                        }
                    } else {
                        if(fsDelete(path)) {
                            updateList = true;
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << platformGetErrorString(platformGetError()) << "\n";
                        }
                    }

                    uiPrompt(TOP_SCREEN, resultMsg.str(), false);

                    freeSpace = fsGetFreeSpace(destination);
                }

                return false;
            });
        } else if(mode == DELETE_TITLE || mode == LAUNCH_TITLE) {
            uiSelectApp(&appTarget, destination, [&](bool &updateList) {
                return onLoop();
            }, [&](App app, bool &updateList) {
                if(mode == DELETE_TITLE) {
                    if(uiPrompt(TOP_SCREEN, "Delete the selected title?", true)) {
                        updateList = true;
                        uiDisplayMessage(TOP_SCREEN, "Deleting title...");
                        AppResult ret = appDelete(app);

                        std::stringstream resultMsg;
                        resultMsg << "Delete ";
                        if(ret == APP_SUCCESS) {
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                        }

                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);

                        freeSpace = fsGetFreeSpace(destination);
                    }
                } else if(mode == LAUNCH_TITLE) {
                    if(uiPrompt(TOP_SCREEN, "Launch the selected title?", true)) {
                        updateList = true;
                        uiDisplayMessage(TOP_SCREEN, "Launching title...");
                        AppResult ret = appLaunch(app);

                        if(ret != APP_SUCCESS) {
                            std::stringstream resultMsg;
                            resultMsg << "Launch failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                            uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                        } else {
                            while(true) {
                            }
                        }
                    }
                }

                return false;
            });
        }

        if(netInstall && !exit) {
            netInstall = false;

            screenClearBuffers(BOTTOM_SCREEN, 0, 0, 0);

            RemoteFile file = uiAcceptRemoteFile(TOP_SCREEN);
            if(file.fd == NULL) {
                continue;
            }

            std::stringstream confirmStream;
            confirmStream << "Install the received application?" << "\n";
            confirmStream << "Size: " << file.fileSize << " bytes (" << std::fixed << std::setprecision(2) << file.fileSize / 1024.0f / 1024.0f << "MB)" << "\n";
            if(uiPrompt(TOP_SCREEN, confirmStream.str(), true)) {
                AppResult ret = appInstall(destination, file.fd, file.fileSize, onProgress);
                std::stringstream resultMsg;
                resultMsg << "Install ";
                if(ret == APP_SUCCESS) {
                    resultMsg << "succeeded!";
                } else {
                    resultMsg << "failed!" << "\n";
                    resultMsg << appGetResultString(ret) << "\n";
                }

                uiPrompt(TOP_SCREEN, resultMsg.str(), false);
            }

            fclose(file.fd);
            continue;
        }

        if(exit) {
            break;
        }
    }

    platformCleanup();
    return 0;
}
<commit_msg>Only show network install option when in installation mode.<commit_after>#include <ctrcommon/input.hpp>
#include <ctrcommon/platform.hpp>
#include <ctrcommon/ui.hpp>

#include <stdio.h>

#include <sstream>
#include <iomanip>

#include <sys/dirent.h>
#include <3ds.h>
#include <ctrcommon/app.hpp>

typedef enum {
    INSTALL_CIA,
    DELETE_CIA,
    DELETE_TITLE,
    LAUNCH_TITLE
} Mode;

int main(int argc, char **argv) {
    if(!platformInit()) {
        return 0;
    }

    bool ninjhax = platformIsNinjhax();

    std::vector<std::string> extensions;
    extensions.push_back("cia");

    MediaType destination = SD;
    Mode mode = INSTALL_CIA;
    bool exit = false;
    bool netInstall = false;
    u64 freeSpace = fsGetFreeSpace(destination);
    auto onLoop = [&]() {
        if(ninjhax && inputIsPressed(BUTTON_START)) {
            exit = true;
            return true;
        }

        bool breakLoop = false;

        if(inputIsPressed(BUTTON_L)) {
            if(destination == SD) {
                destination = NAND;
            } else {
                destination = SD;
            }

            freeSpace = fsGetFreeSpace(destination);
            if(mode == DELETE_TITLE) {
                breakLoop = true;
            }
        }

        if(inputIsPressed(BUTTON_R)) {
            if(mode == INSTALL_CIA) {
                mode = DELETE_CIA;
            } else if(mode == DELETE_CIA) {
                mode = DELETE_TITLE;
                breakLoop = true;
            } else if(mode == DELETE_TITLE) {
                mode = LAUNCH_TITLE;
            } else if(mode == LAUNCH_TITLE) {
                mode = INSTALL_CIA;
                breakLoop = true;
            }
        }

        if(mode == INSTALL_CIA && inputIsPressed(BUTTON_Y)) {
            netInstall = true;
            breakLoop = true;
        }

        std::stringstream stream;
        stream << "Free Space: " << freeSpace << " bytes (" << std::fixed << std::setprecision(2) << freeSpace / 1024.0f / 1024.0f << "MB)" << "\n";
        stream << "Destination: " << (destination == NAND ? "NAND" : "SD") << ", Mode: " << (mode == INSTALL_CIA ? "Install CIA" : mode == DELETE_CIA ? "Delete CIA" : mode == DELETE_TITLE ? "Delete Title" : "Launch Title") << "\n";
        stream << "L - Switch Destination, R - Switch Mode" << "\n";
        if(mode == INSTALL_CIA) {
            stream << "X - Install all CIAs in the current directory" << "\n";
            stream << "Y - Receive an app over the network" << "\n";
        } else if(mode == DELETE_CIA) {
            stream << "X - Delete all CIAs in the current directory" << "\n";
        }

        if(ninjhax) {
            stream << "START - Exit to launcher" << "\n";
        }

        std::string str = stream.str();
        screenDrawString(str, (screenGetWidth() - screenGetStrWidth(str)) / 2, screenGetHeight() - 4 - screenGetStrHeight(str), 255, 255, 255);

        return breakLoop;
    };

    auto onProgress = [&](u64 pos, u64 totalSize) {
        std::stringstream details;
        details << "(" << std::fixed << std::setprecision(2) << ((double) pos / 1024.0 / 1024.0) << "MB / " << std::fixed << std::setprecision(2) << ((double) totalSize / 1024.0 / 1024.0) << "MB)" << "\n";
        details << "Press B to cancel.";

        u32 progress = (u32) (((double) pos / (double) totalSize) * 100);
        uiDisplayProgress(TOP_SCREEN, "Installing", details.str(), true, progress);
        inputPoll();
        return !inputIsPressed(BUTTON_B);
    };

    while(platformIsRunning()) {
        std::string fileTarget;
        App appTarget;
        if(mode == INSTALL_CIA || mode == DELETE_CIA) {
            uiSelectFile(&fileTarget, "/", extensions, [&](const std::string currDirectory, bool inRoot, bool &updateList) {
                if(inputIsPressed(BUTTON_X)) {
                    std::stringstream confirmMsg;
                    if(mode == INSTALL_CIA) {
                        confirmMsg << "Install ";
                    } else {
                        confirmMsg << "Delete ";
                    }

                    confirmMsg << "all CIAs in the current directory?";
                    if(uiPrompt(TOP_SCREEN, confirmMsg.str(), true)) {
                        bool failed = false;
                        std::vector<FileInfo> contents = fsGetDirectoryContents(currDirectory);
                        for(std::vector<FileInfo>::iterator it = contents.begin(); it != contents.end(); it++) {
                            std::string path = (*it).path;
                            std::string fileName = (*it).name;
                            if(!fsIsDirectory(path) && fsHasExtensions(path, extensions)) {
                                if(mode == INSTALL_CIA) {
                                    AppResult ret = appInstallFile(destination, path, onProgress);
                                    if(ret != APP_SUCCESS) {
                                        std::stringstream resultMsg;
                                        resultMsg << "Install failed!" << "\n";
                                        resultMsg << fileName << "\n";
                                        resultMsg << appGetResultString(ret) << "\n";
                                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                                        failed = true;
                                        break;
                                    }
                                } else {
                                    if(!fsDelete(path)) {
                                        std::stringstream resultMsg;
                                        resultMsg << "Delete failed!" << "\n";
                                        resultMsg << fileName << "\n";
                                        resultMsg << platformGetErrorString(platformGetError()) << "\n";
                                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                                        failed = true;
                                        break;
                                    } else {
                                        updateList = true;
                                    }
                                }
                            }
                        }

                        if(!failed) {
                            uiPrompt(TOP_SCREEN, "Install succeeded!\n", false);
                        }

                        freeSpace = fsGetFreeSpace(destination);
                    }
                }

                return onLoop();
            }, [&](const std::string path, bool &updateList) {
                std::stringstream confirmMsg;
                if(mode == INSTALL_CIA) {
                    confirmMsg << "Install ";
                } else {
                    confirmMsg << "Delete ";
                }

                confirmMsg << "the selected CIA?";
                if(uiPrompt(TOP_SCREEN, confirmMsg.str(), true)) {
                    std::stringstream resultMsg;
                    if(mode == INSTALL_CIA) {
                        resultMsg << "Install ";
                    } else {
                        resultMsg << "Delete ";
                    }

                    if(mode == INSTALL_CIA) {
                        AppResult ret = appInstallFile(destination, path, onProgress);
                        if(ret == APP_SUCCESS) {
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                        }
                    } else {
                        if(fsDelete(path)) {
                            updateList = true;
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << platformGetErrorString(platformGetError()) << "\n";
                        }
                    }

                    uiPrompt(TOP_SCREEN, resultMsg.str(), false);

                    freeSpace = fsGetFreeSpace(destination);
                }

                return false;
            });
        } else if(mode == DELETE_TITLE || mode == LAUNCH_TITLE) {
            uiSelectApp(&appTarget, destination, [&](bool &updateList) {
                return onLoop();
            }, [&](App app, bool &updateList) {
                if(mode == DELETE_TITLE) {
                    if(uiPrompt(TOP_SCREEN, "Delete the selected title?", true)) {
                        updateList = true;
                        uiDisplayMessage(TOP_SCREEN, "Deleting title...");
                        AppResult ret = appDelete(app);

                        std::stringstream resultMsg;
                        resultMsg << "Delete ";
                        if(ret == APP_SUCCESS) {
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                        }

                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);

                        freeSpace = fsGetFreeSpace(destination);
                    }
                } else if(mode == LAUNCH_TITLE) {
                    if(uiPrompt(TOP_SCREEN, "Launch the selected title?", true)) {
                        updateList = true;
                        uiDisplayMessage(TOP_SCREEN, "Launching title...");
                        AppResult ret = appLaunch(app);

                        if(ret != APP_SUCCESS) {
                            std::stringstream resultMsg;
                            resultMsg << "Launch failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                            uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                        } else {
                            while(true) {
                            }
                        }
                    }
                }

                return false;
            });
        }

        if(netInstall && !exit) {
            netInstall = false;

            screenClearBuffers(BOTTOM_SCREEN, 0, 0, 0);

            RemoteFile file = uiAcceptRemoteFile(TOP_SCREEN);
            if(file.fd == NULL) {
                continue;
            }

            std::stringstream confirmStream;
            confirmStream << "Install the received application?" << "\n";
            confirmStream << "Size: " << file.fileSize << " bytes (" << std::fixed << std::setprecision(2) << file.fileSize / 1024.0f / 1024.0f << "MB)" << "\n";
            if(uiPrompt(TOP_SCREEN, confirmStream.str(), true)) {
                AppResult ret = appInstall(destination, file.fd, file.fileSize, onProgress);
                std::stringstream resultMsg;
                resultMsg << "Install ";
                if(ret == APP_SUCCESS) {
                    resultMsg << "succeeded!";
                } else {
                    resultMsg << "failed!" << "\n";
                    resultMsg << appGetResultString(ret) << "\n";
                }

                uiPrompt(TOP_SCREEN, resultMsg.str(), false);
            }

            fclose(file.fd);
            continue;
        }

        if(exit) {
            break;
        }
    }

    platformCleanup();
    return 0;
}
<|endoftext|>


<commit_before>// Copyright 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/renderer/compositor_bindings/web_external_texture_layer_impl.h"

#include "cc/layers/texture_layer.h"
#include "cc/resources/resource_update_queue.h"
#include "cc/resources/single_release_callback.h"
#include "cc/resources/texture_mailbox.h"
#include "third_party/WebKit/public/platform/WebExternalTextureLayerClient.h"
#include "third_party/WebKit/public/platform/WebExternalTextureMailbox.h"
#include "third_party/WebKit/public/platform/WebFloatRect.h"
#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "webkit/renderer/compositor_bindings/web_external_bitmap_impl.h"
#include "webkit/renderer/compositor_bindings/web_layer_impl.h"

using cc::TextureLayer;
using cc::ResourceUpdateQueue;

namespace webkit {

WebExternalTextureLayerImpl::WebExternalTextureLayerImpl(
    blink::WebExternalTextureLayerClient* client)
    : client_(client) {
  cc::TextureLayerClient* cc_client = client_ ? this : NULL;
  scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(cc_client);
  layer->SetIsDrawable(true);
  layer_.reset(new WebLayerImpl(layer));
}

WebExternalTextureLayerImpl::~WebExternalTextureLayerImpl() {
  static_cast<TextureLayer*>(layer_->layer())->ClearClient();
}

blink::WebLayer* WebExternalTextureLayerImpl::layer() { return layer_.get(); }

void WebExternalTextureLayerImpl::clearTexture() {
  TextureLayer *layer = static_cast<TextureLayer*>(layer_->layer());
  layer->ClearTexture();
}

void WebExternalTextureLayerImpl::setOpaque(bool opaque) {
  static_cast<TextureLayer*>(layer_->layer())->SetContentsOpaque(opaque);
}

void WebExternalTextureLayerImpl::setPremultipliedAlpha(
    bool premultiplied_alpha) {
  static_cast<TextureLayer*>(layer_->layer())->SetPremultipliedAlpha(
      premultiplied_alpha);
}

void WebExternalTextureLayerImpl::setBlendBackgroundColor(bool blend) {
  static_cast<TextureLayer*>(layer_->layer())->SetBlendBackgroundColor(blend);
}

void WebExternalTextureLayerImpl::setRateLimitContext(bool rate_limit) {
  static_cast<TextureLayer*>(layer_->layer())->SetRateLimitContext(rate_limit);
}

bool WebExternalTextureLayerImpl::PrepareTextureMailbox(
    cc::TextureMailbox* mailbox,
    scoped_ptr<cc::SingleReleaseCallback>* release_callback,
    bool use_shared_memory) {
  blink::WebExternalTextureMailbox client_mailbox;
  WebExternalBitmapImpl* bitmap = NULL;

  if (use_shared_memory)
    bitmap = AllocateBitmap();
  if (!client_->prepareMailbox(&client_mailbox, bitmap)) {
    if (bitmap)
      free_bitmaps_.push_back(bitmap);
    return false;
  }
  gpu::Mailbox name;
  name.SetName(client_mailbox.name);
  if (bitmap) {
    *mailbox = cc::TextureMailbox(bitmap->shared_memory(), bitmap->size());
  } else {
    *mailbox =
        cc::TextureMailbox(name, GL_TEXTURE_2D, client_mailbox.syncPoint);
  }

  if (mailbox->IsValid()) {
    *release_callback = cc::SingleReleaseCallback::Create(base::Bind(
        &WebExternalTextureLayerImpl::DidReleaseMailbox,
        this->AsWeakPtr(),
        client_mailbox,
        bitmap));
  }

  return true;
}

WebExternalBitmapImpl* WebExternalTextureLayerImpl::AllocateBitmap() {
  if (!free_bitmaps_.empty()) {
    WebExternalBitmapImpl* result = free_bitmaps_.back();
    free_bitmaps_.weak_erase(free_bitmaps_.end() - 1);
    return result;
  }
  return new WebExternalBitmapImpl;
}

// static
void WebExternalTextureLayerImpl::DidReleaseMailbox(
    base::WeakPtr<WebExternalTextureLayerImpl> layer,
    const blink::WebExternalTextureMailbox& mailbox,
    WebExternalBitmapImpl* bitmap,
    unsigned sync_point,
    bool lost_resource) {
  if (lost_resource || !layer) {
    delete bitmap;
    return;
  }

  blink::WebExternalTextureMailbox available_mailbox;
  memcpy(available_mailbox.name, mailbox.name, sizeof(available_mailbox.name));
  available_mailbox.syncPoint = sync_point;
  if (bitmap)
    layer->free_bitmaps_.push_back(bitmap);
  layer->client_->mailboxReleased(available_mailbox);
}

}  // namespace webkit
<commit_msg>Pass information about overlay support in a mailbox from blink to CC.<commit_after>// Copyright 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/renderer/compositor_bindings/web_external_texture_layer_impl.h"

#include "cc/layers/texture_layer.h"
#include "cc/resources/resource_update_queue.h"
#include "cc/resources/single_release_callback.h"
#include "cc/resources/texture_mailbox.h"
#include "third_party/WebKit/public/platform/WebExternalTextureLayerClient.h"
#include "third_party/WebKit/public/platform/WebExternalTextureMailbox.h"
#include "third_party/WebKit/public/platform/WebFloatRect.h"
#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "webkit/renderer/compositor_bindings/web_external_bitmap_impl.h"
#include "webkit/renderer/compositor_bindings/web_layer_impl.h"

using cc::TextureLayer;
using cc::ResourceUpdateQueue;

namespace webkit {

WebExternalTextureLayerImpl::WebExternalTextureLayerImpl(
    blink::WebExternalTextureLayerClient* client)
    : client_(client) {
  cc::TextureLayerClient* cc_client = client_ ? this : NULL;
  scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(cc_client);
  layer->SetIsDrawable(true);
  layer_.reset(new WebLayerImpl(layer));
}

WebExternalTextureLayerImpl::~WebExternalTextureLayerImpl() {
  static_cast<TextureLayer*>(layer_->layer())->ClearClient();
}

blink::WebLayer* WebExternalTextureLayerImpl::layer() { return layer_.get(); }

void WebExternalTextureLayerImpl::clearTexture() {
  TextureLayer *layer = static_cast<TextureLayer*>(layer_->layer());
  layer->ClearTexture();
}

void WebExternalTextureLayerImpl::setOpaque(bool opaque) {
  static_cast<TextureLayer*>(layer_->layer())->SetContentsOpaque(opaque);
}

void WebExternalTextureLayerImpl::setPremultipliedAlpha(
    bool premultiplied_alpha) {
  static_cast<TextureLayer*>(layer_->layer())->SetPremultipliedAlpha(
      premultiplied_alpha);
}

void WebExternalTextureLayerImpl::setBlendBackgroundColor(bool blend) {
  static_cast<TextureLayer*>(layer_->layer())->SetBlendBackgroundColor(blend);
}

void WebExternalTextureLayerImpl::setRateLimitContext(bool rate_limit) {
  static_cast<TextureLayer*>(layer_->layer())->SetRateLimitContext(rate_limit);
}

bool WebExternalTextureLayerImpl::PrepareTextureMailbox(
    cc::TextureMailbox* mailbox,
    scoped_ptr<cc::SingleReleaseCallback>* release_callback,
    bool use_shared_memory) {
  blink::WebExternalTextureMailbox client_mailbox;
  WebExternalBitmapImpl* bitmap = NULL;

  if (use_shared_memory)
    bitmap = AllocateBitmap();
  if (!client_->prepareMailbox(&client_mailbox, bitmap)) {
    if (bitmap)
      free_bitmaps_.push_back(bitmap);
    return false;
  }
  gpu::Mailbox name;
  name.SetName(client_mailbox.name);
  if (bitmap) {
    *mailbox = cc::TextureMailbox(bitmap->shared_memory(), bitmap->size());
  } else {
    *mailbox =
        cc::TextureMailbox(name, GL_TEXTURE_2D, client_mailbox.syncPoint);
  }
  mailbox->set_allow_overlay(client_mailbox.allowOverlay);

  if (mailbox->IsValid()) {
    *release_callback = cc::SingleReleaseCallback::Create(base::Bind(
        &WebExternalTextureLayerImpl::DidReleaseMailbox,
        this->AsWeakPtr(),
        client_mailbox,
        bitmap));
  }

  return true;
}

WebExternalBitmapImpl* WebExternalTextureLayerImpl::AllocateBitmap() {
  if (!free_bitmaps_.empty()) {
    WebExternalBitmapImpl* result = free_bitmaps_.back();
    free_bitmaps_.weak_erase(free_bitmaps_.end() - 1);
    return result;
  }
  return new WebExternalBitmapImpl;
}

// static
void WebExternalTextureLayerImpl::DidReleaseMailbox(
    base::WeakPtr<WebExternalTextureLayerImpl> layer,
    const blink::WebExternalTextureMailbox& mailbox,
    WebExternalBitmapImpl* bitmap,
    unsigned sync_point,
    bool lost_resource) {
  if (lost_resource || !layer) {
    delete bitmap;
    return;
  }

  blink::WebExternalTextureMailbox available_mailbox;
  memcpy(available_mailbox.name, mailbox.name, sizeof(available_mailbox.name));
  available_mailbox.syncPoint = sync_point;
  if (bitmap)
    layer->free_bitmaps_.push_back(bitmap);
  layer->client_->mailboxReleased(available_mailbox);
}

}  // namespace webkit
<|endoftext|>


<commit_before>//-----------------------------------------------------------------------------
// Copyright (c) 2015, Jeff Hutchinson
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * 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.
//
// * Neither the name of D3D11Test nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
//-----------------------------------------------------------------------------

// Require MSVC compiler for this application
#ifndef _MSC_VER
#error "You must use MSVC to compile this application."
#endif // _MSC_VER

#include <stdlib.h>
#include <SDL.h>
#include <SDL_syswm.h>

// Windows specific header + D3D11 SDK header
#include <Windows.h>
#include <d3d11.h>

// link with D3D11.lib
#pragma comment(lib, "D3D11.lib")

// SDL2 hack.
#ifdef main
#undef main
#endif // main

// used to signify that the variable is being outputted
#define OUT

HWND getWindowHandle(SDL_Window *window);
bool createD3D11DeviceAndSwapChain(HWND window, OUT ID3D11Device *&device, OUT IDXGISwapChain *&swapChain, OUT ID3D11DeviceContext *&context);
void render(ID3D11Device *device, ID3D11DeviceContext *context);

int main(int argc, const char **argv) {
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);

	// create window
	SDL_Window *window = SDL_CreateWindow("D3D11 Test Application", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1366, 768, SDL_WINDOW_SHOWN);
	if (window == nullptr) {
		SDL_Quit();
		return 1;
	}

	// get window handle from the window
	HWND windowHandle = getWindowHandle(window);
	if (windowHandle == nullptr) {
		SDL_DestroyWindow(window);
		SDL_Quit();
		return 2;
	}

	ID3D11Device *device = nullptr;
	IDXGISwapChain *swapChain = nullptr;
	ID3D11DeviceContext *context = nullptr;
	bool r = createD3D11DeviceAndSwapChain(windowHandle, device, swapChain, context);
	if (r == false) {
		SDL_DestroyWindow(window);
		SDL_Quit();
		return 3;
	}

	// render target view
	ID3D11RenderTargetView *rtv = nullptr;
	{
		ID3D11Texture2D *backBuffer = nullptr;
		if (swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer) != S_OK) {
			SDL_DestroyWindow(window);
			SDL_Quit();
			return 4;
		}
		HRESULT check = device->CreateRenderTargetView(backBuffer, NULL, &rtv);
		// release back buffer texture as it already has been set.
		backBuffer->Release();
		if (check != S_OK) {
			SDL_DestroyWindow(window);
			SDL_Quit();
			return 5;
		}
		context->OMSetRenderTargets(1, &rtv, NULL);
	}

	// set viewport
	D3D11_VIEWPORT vp;
	vp.Width = (FLOAT)1366;
	vp.Height = (FLOAT)768;
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	context->RSSetViewports(1, &vp);

	SDL_Event event;
	bool running = true;
	while (running) {
		// Run event loop.
		while (SDL_PollEvent(&event)) {
			// check to see if we fired a quit event. If we did, we're done
			// running the program.
			if (event.type == SDL_QUIT) {
				running = false;
				break;
			}
		}

		// clear color
		static float clearColor[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
		context->ClearRenderTargetView(rtv, clearColor);

		render(device, context);

		// swap buffer
		swapChain->Present(0, 0);
	}

	// cleanup
	SDL_DestroyWindow(window);
	SDL_Quit();
	return 0;
}

HWND getWindowHandle(SDL_Window *window) {
	SDL_SysWMinfo info;
	SDL_VERSION(&info.version);
	if (!SDL_GetWindowWMInfo(window, &info))
		return nullptr;

	return info.info.win.window;
}

bool createD3D11DeviceAndSwapChain(HWND window, OUT ID3D11Device *&device, OUT IDXGISwapChain *&swapChain, OUT ID3D11DeviceContext *&context) {
	// create swap chain description
	DXGI_SWAP_CHAIN_DESC swapDesc;
	ZeroMemory(&swapDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
	swapDesc.BufferCount = 1; // how many back buffers
	swapDesc.BufferDesc.Width = 1366; // window width
	swapDesc.BufferDesc.Height = 768; // window height
	swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // standard backbuffer format
	swapDesc.BufferDesc.RefreshRate.Numerator = 60; // vsync
	swapDesc.BufferDesc.RefreshRate.Denominator = 1; // vsync
	swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // yes we are rendering to a window
	swapDesc.OutputWindow = window; // the window we are outputting to
	swapDesc.SampleDesc.Count = 1;
	swapDesc.SampleDesc.Quality = 0; // Antialiasing
	swapDesc.Windowed = true; // we are not in fullscreen

	// request feature level 11_0
	D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
	UINT featureLevelCount = 1;
	D3D_FEATURE_LEVEL featureLevelSupported;

	HRESULT r = D3D11CreateDeviceAndSwapChain(
		NULL,								// adapter
		D3D_DRIVER_TYPE_HARDWARE,	// device type
		NULL,								// do we want software emulation for features not supported?
		0,									// device flags
		&featureLevel,					// feature level(s) requested
		featureLevelCount,			// amount of feature level(s) requested
		D3D11_SDK_VERSION,			// version of the DX11 SDK
		&swapDesc,						// swap chain description
		&swapChain,						// OUT the swap chain pointer
		&device,							// OUT the d3d11 device
		&featureLevelSupported,		// OUT the d3d11 feature level that is supported on this computer.
		&context							// OUT the d3d11 context
	);
	if (r == S_OK)
		return true;
	return false;
}

void render(ID3D11Device *device, ID3D11DeviceContext *context) {

}<commit_msg>cleanup<commit_after>//-----------------------------------------------------------------------------
// Copyright (c) 2015, Jeff Hutchinson
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * 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.
//
// * Neither the name of D3D11Test nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
//-----------------------------------------------------------------------------

// Require MSVC compiler for this application
#ifndef _MSC_VER
#error "You must use MSVC to compile this application."
#endif // _MSC_VER

#include <stdlib.h>
#include <SDL.h>
#include <SDL_syswm.h>

// Windows specific header + D3D11 SDK header
#include <Windows.h>
#include <d3d11.h>

// link with D3D11.lib
#pragma comment(lib, "D3D11.lib")

// SDL2 hack.
#ifdef main
#undef main
#endif // main

// used to signify that the variable is being outputted
#define OUT

HWND getWindowHandle(SDL_Window *window);
bool createD3D11DeviceAndSwapChain(HWND window, OUT ID3D11Device *&device, OUT IDXGISwapChain *&swapChain, OUT ID3D11DeviceContext *&context);
void render(ID3D11Device *device, ID3D11DeviceContext *context);

int main(int argc, const char **argv) {
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);

	// create window
	SDL_Window *window = SDL_CreateWindow("D3D11 Test Application", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1366, 768, SDL_WINDOW_SHOWN);
	if (window == nullptr) {
		SDL_Quit();
		return 1;
	}

	// get window handle from the window
	HWND windowHandle = getWindowHandle(window);
	if (windowHandle == nullptr) {
		SDL_DestroyWindow(window);
		SDL_Quit();
		return 2;
	}

	ID3D11Device *device = nullptr;
	IDXGISwapChain *swapChain = nullptr;
	ID3D11DeviceContext *context = nullptr;
	bool r = createD3D11DeviceAndSwapChain(windowHandle, device, swapChain, context);
	if (r == false) {
		SDL_DestroyWindow(window);
		SDL_Quit();
		return 3;
	}

	// render target view
	ID3D11RenderTargetView *rtv = nullptr;
	{
		ID3D11Texture2D *backBuffer = nullptr;
		if (swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<LPVOID*>(&backBuffer)) != S_OK) {
			SDL_DestroyWindow(window);
			SDL_Quit();
			return 4;
		}
		HRESULT check = device->CreateRenderTargetView(backBuffer, NULL, &rtv);
		// release back buffer texture as it already has been set.
		backBuffer->Release();
		if (check != S_OK) {
			SDL_DestroyWindow(window);
			SDL_Quit();
			return 5;
		}
		context->OMSetRenderTargets(1, &rtv, NULL);
	}

	// set viewport
	D3D11_VIEWPORT vp;
	vp.Width = 1366.0f;
	vp.Height = 768.0f;
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	context->RSSetViewports(1, &vp);

	// clear color
	static float clearColor[4] = { 1.0f, 0.0f, 0.0f, 1.0f };

	SDL_Event event;
	bool running = true;
	while (running) {
		// Run event loop.
		while (SDL_PollEvent(&event)) {
			// check to see if we fired a quit event. If we did, we're done
			// running the program.
			if (event.type == SDL_QUIT) {
				running = false;
				break;
			}
		}

		// set canvas clear color
		context->ClearRenderTargetView(rtv, clearColor);

		// perform any additional render logic
		render(device, context);

		// swap buffer
		swapChain->Present(0, 0);
	}

	// cleanup
	SDL_DestroyWindow(window);
	SDL_Quit();
	return 0;
}

HWND getWindowHandle(SDL_Window *window) {
	SDL_SysWMinfo info;
	SDL_VERSION(&info.version);
	if (!SDL_GetWindowWMInfo(window, &info))
		return nullptr;

	return info.info.win.window;
}

bool createD3D11DeviceAndSwapChain(HWND window, OUT ID3D11Device *&device, OUT IDXGISwapChain *&swapChain, OUT ID3D11DeviceContext *&context) {
	// create swap chain description
	DXGI_SWAP_CHAIN_DESC swapDesc;
	ZeroMemory(&swapDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
	swapDesc.BufferCount = 1; // how many back buffers
	swapDesc.BufferDesc.Width = 1366; // window width
	swapDesc.BufferDesc.Height = 768; // window height
	swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // standard backbuffer format
	swapDesc.BufferDesc.RefreshRate.Numerator = 60; // vsync
	swapDesc.BufferDesc.RefreshRate.Denominator = 1; // vsync
	swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // yes we are rendering to a window
	swapDesc.OutputWindow = window; // the window we are outputting to
	swapDesc.SampleDesc.Count = 1;
	swapDesc.SampleDesc.Quality = 0; // Antialiasing
	swapDesc.Windowed = true; // we are not in fullscreen

	// request feature level 11_0
	D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
	UINT featureLevelCount = 1;
	D3D_FEATURE_LEVEL featureLevelSupported;

	HRESULT r = D3D11CreateDeviceAndSwapChain(
		NULL,								// adapter
		D3D_DRIVER_TYPE_HARDWARE,	// device type
		NULL,								// do we want software emulation for features not supported?
		0,									// device flags
		&featureLevel,					// feature level(s) requested
		featureLevelCount,			// amount of feature level(s) requested
		D3D11_SDK_VERSION,			// version of the DX11 SDK
		&swapDesc,						// swap chain description
		&swapChain,						// OUT the swap chain pointer
		&device,							// OUT the d3d11 device
		&featureLevelSupported,		// OUT the d3d11 feature level that is supported on this computer.
		&context							// OUT the d3d11 context
	);
	if (r == S_OK)
		return true;
	return false;
}

void render(ID3D11Device *device, ID3D11DeviceContext *context) {

}<|endoftext|>


<commit_before><commit_msg>include config.h first otherwise bad things happen<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/glue/webcursor.h"

#include <gdk/gdk.h>
#include <gtk/gtk.h>

#include "base/logging.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h"

using WebKit::WebCursorInfo;

namespace {

// webcursor_gtk_data.h is taken directly from WebKit's CursorGtk.h.
#include "webkit/glue/webcursor_gtk_data.h"

// This helper function is taken directly from WebKit's CursorGtk.cpp.
// It attempts to create a custom cursor from the data inlined in
// webcursor_gtk_data.h.
GdkCursor* GetInlineCustomCursor(CustomCursorType type) {
  const CustomCursor& custom = CustomCursors[type];
  GdkCursor* cursor = gdk_cursor_new_from_name(gdk_display_get_default(),
                                               custom.name);
  if (!cursor) {
    const GdkColor fg = { 0, 0, 0, 0 };
    const GdkColor bg = { 65535, 65535, 65535, 65535 };
    GdkPixmap* source = gdk_bitmap_create_from_data(NULL, custom.bits,
                                                    32, 32);
    GdkPixmap* mask = gdk_bitmap_create_from_data(NULL, custom.mask_bits,
                                                  32, 32);
    cursor = gdk_cursor_new_from_pixmap(source, mask, &fg, &bg,
                                        custom.hot_x, custom.hot_y);
    g_object_unref(source);
    g_object_unref(mask);
  }
  return cursor;
}

// For GTK 2.16 and beyond, GDK_BLANK_CURSOR is available. Before, we have to
// use a custom cursor.
#if !GTK_CHECK_VERSION(2, 16, 0)
// Get/create a custom cursor which is invisible.
GdkCursor* GetInvisibleCustomCursor() {
  const char bits[] = { 0 };
  const GdkColor color = { 0, 0, 0, 0 };
  GdkPixmap* bitmap = gdk_bitmap_create_from_data(NULL, bits, 1, 1);
  GdkCursor* cursor =
      gdk_cursor_new_from_pixmap(bitmap, bitmap, &color, &color, 0, 0);
  g_object_unref(bitmap);
  return cursor;
}
#endif

}  // end anonymous namespace

int WebCursor::GetCursorType() const {
  // http://library.gnome.org/devel/gdk/2.12/gdk-Cursors.html has images
  // of the default X theme, but beware that the user's cursor theme can
  // change everything.
  switch (type_) {
    case WebCursorInfo::TypePointer:
      return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeCross:
      return GDK_CROSS;
    case WebCursorInfo::TypeHand:
      return GDK_HAND2;
    case WebCursorInfo::TypeIBeam:
      return GDK_XTERM;
    case WebCursorInfo::TypeWait:
      return GDK_WATCH;
    case WebCursorInfo::TypeHelp:
      return GDK_QUESTION_ARROW;
    case WebCursorInfo::TypeEastResize:
      return GDK_RIGHT_SIDE;
    case WebCursorInfo::TypeNorthResize:
      return GDK_TOP_SIDE;
    case WebCursorInfo::TypeNorthEastResize:
      return GDK_TOP_RIGHT_CORNER;
    case WebCursorInfo::TypeNorthWestResize:
      return GDK_TOP_LEFT_CORNER;
    case WebCursorInfo::TypeSouthResize:
      return GDK_BOTTOM_SIDE;
    case WebCursorInfo::TypeSouthEastResize:
      return GDK_BOTTOM_RIGHT_CORNER;
    case WebCursorInfo::TypeSouthWestResize:
      return GDK_BOTTOM_LEFT_CORNER;
    case WebCursorInfo::TypeWestResize:
      return GDK_LEFT_SIDE;
    case WebCursorInfo::TypeNorthSouthResize:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeEastWestResize:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeNorthEastSouthWestResize:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeNorthWestSouthEastResize:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeColumnResize:
      return GDK_SB_H_DOUBLE_ARROW;  // TODO(evanm): is this correct?
    case WebCursorInfo::TypeRowResize:
      return GDK_SB_V_DOUBLE_ARROW;  // TODO(evanm): is this correct?
    case WebCursorInfo::TypeMiddlePanning:
      return GDK_FLEUR;
    case WebCursorInfo::TypeEastPanning:
      return GDK_SB_RIGHT_ARROW;
    case WebCursorInfo::TypeNorthPanning:
      return GDK_SB_UP_ARROW;
    case WebCursorInfo::TypeNorthEastPanning:
      return GDK_TOP_RIGHT_CORNER;
    case WebCursorInfo::TypeNorthWestPanning:
      return GDK_TOP_LEFT_CORNER;
    case WebCursorInfo::TypeSouthPanning:
      return GDK_SB_DOWN_ARROW;
    case WebCursorInfo::TypeSouthEastPanning:
      return GDK_BOTTOM_RIGHT_CORNER;
    case WebCursorInfo::TypeSouthWestPanning:
      return GDK_BOTTOM_LEFT_CORNER;
    case WebCursorInfo::TypeWestPanning:
      return GDK_SB_LEFT_ARROW;
    case WebCursorInfo::TypeMove:
      return GDK_FLEUR;
    case WebCursorInfo::TypeVerticalText:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeCell:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeContextMenu:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeAlias:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeProgress:
      return GDK_WATCH;
    case WebCursorInfo::TypeNoDrop:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeCopy:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeNone:
// See comment above |GetInvisibleCustomCursor()|.
#if !GTK_CHECK_VERSION(2, 16, 0)
      return GDK_CURSOR_IS_PIXMAP;
#else
      return GDK_BLANK_CURSOR;
#endif
    case WebCursorInfo::TypeNotAllowed:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeZoomIn:
    case WebCursorInfo::TypeZoomOut:
    case WebCursorInfo::TypeCustom:
      return GDK_CURSOR_IS_PIXMAP;
  }
  NOTREACHED();
  return GDK_LAST_CURSOR;
}

GdkCursor* WebCursor::GetCustomCursor() const {
  switch (type_) {
// See comment above |GetInvisibleCustomCursor()|.
#if !GTK_CHECK_VERSION(2, 16, 0)
    case WebCursorInfo::TypeNone:
      return GetInvisibleCustomCursor();
#endif
    case WebCursorInfo::TypeZoomIn:
      return GetInlineCustomCursor(CustomCursorZoomIn);
    case WebCursorInfo::TypeZoomOut:
      return GetInlineCustomCursor(CustomCursorZoomOut);
  }

  if (type_ != WebCursorInfo::TypeCustom) {
    NOTREACHED();
    return NULL;
  }

  const guchar* data = reinterpret_cast<const guchar*>(&custom_data_[0]);
  GdkPixbuf* pixbuf =
      gdk_pixbuf_new_from_data(data,
                               GDK_COLORSPACE_RGB,
                               TRUE,  // has_alpha
                               8,     // bits_per_sample
                               custom_size_.width(),      // width
                               custom_size_.height(),     // height
                               custom_size_.width() * 4,  // row stride
                               NULL,   // data destroy function
                               NULL);  // data destroy function extra data

  GdkCursor* cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(),
                                                 pixbuf,
                                                 hotspot_.x(),
                                                 hotspot_.y());

  gdk_pixbuf_unref(pixbuf);

  return cursor;
}

void WebCursor::InitPlatformData() {
  return;
}

bool WebCursor::SerializePlatformData(Pickle* pickle) const {
  return true;
}

bool WebCursor::DeserializePlatformData(const Pickle* pickle, void** iter) {
  return true;
}

bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
  return true;
}

void WebCursor::CleanupPlatformData() {
  return;
}

void WebCursor::CopyPlatformData(const WebCursor& other) {
  return;
}
<commit_msg>GTK: fix decoding of custom cursor bytes.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/glue/webcursor.h"

#include <gdk/gdk.h>
#include <gtk/gtk.h>

#include "base/logging.h"
#include "gfx/gtk_util.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h"

using WebKit::WebCursorInfo;

namespace {

// webcursor_gtk_data.h is taken directly from WebKit's CursorGtk.h.
#include "webkit/glue/webcursor_gtk_data.h"

// This helper function is taken directly from WebKit's CursorGtk.cpp.
// It attempts to create a custom cursor from the data inlined in
// webcursor_gtk_data.h.
GdkCursor* GetInlineCustomCursor(CustomCursorType type) {
  const CustomCursor& custom = CustomCursors[type];
  GdkCursor* cursor = gdk_cursor_new_from_name(gdk_display_get_default(),
                                               custom.name);
  if (!cursor) {
    const GdkColor fg = { 0, 0, 0, 0 };
    const GdkColor bg = { 65535, 65535, 65535, 65535 };
    GdkPixmap* source = gdk_bitmap_create_from_data(NULL, custom.bits,
                                                    32, 32);
    GdkPixmap* mask = gdk_bitmap_create_from_data(NULL, custom.mask_bits,
                                                  32, 32);
    cursor = gdk_cursor_new_from_pixmap(source, mask, &fg, &bg,
                                        custom.hot_x, custom.hot_y);
    g_object_unref(source);
    g_object_unref(mask);
  }
  return cursor;
}

// For GTK 2.16 and beyond, GDK_BLANK_CURSOR is available. Before, we have to
// use a custom cursor.
#if !GTK_CHECK_VERSION(2, 16, 0)
// Get/create a custom cursor which is invisible.
GdkCursor* GetInvisibleCustomCursor() {
  const char bits[] = { 0 };
  const GdkColor color = { 0, 0, 0, 0 };
  GdkPixmap* bitmap = gdk_bitmap_create_from_data(NULL, bits, 1, 1);
  GdkCursor* cursor =
      gdk_cursor_new_from_pixmap(bitmap, bitmap, &color, &color, 0, 0);
  g_object_unref(bitmap);
  return cursor;
}
#endif

}  // end anonymous namespace

int WebCursor::GetCursorType() const {
  // http://library.gnome.org/devel/gdk/2.12/gdk-Cursors.html has images
  // of the default X theme, but beware that the user's cursor theme can
  // change everything.
  switch (type_) {
    case WebCursorInfo::TypePointer:
      return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeCross:
      return GDK_CROSS;
    case WebCursorInfo::TypeHand:
      return GDK_HAND2;
    case WebCursorInfo::TypeIBeam:
      return GDK_XTERM;
    case WebCursorInfo::TypeWait:
      return GDK_WATCH;
    case WebCursorInfo::TypeHelp:
      return GDK_QUESTION_ARROW;
    case WebCursorInfo::TypeEastResize:
      return GDK_RIGHT_SIDE;
    case WebCursorInfo::TypeNorthResize:
      return GDK_TOP_SIDE;
    case WebCursorInfo::TypeNorthEastResize:
      return GDK_TOP_RIGHT_CORNER;
    case WebCursorInfo::TypeNorthWestResize:
      return GDK_TOP_LEFT_CORNER;
    case WebCursorInfo::TypeSouthResize:
      return GDK_BOTTOM_SIDE;
    case WebCursorInfo::TypeSouthEastResize:
      return GDK_BOTTOM_RIGHT_CORNER;
    case WebCursorInfo::TypeSouthWestResize:
      return GDK_BOTTOM_LEFT_CORNER;
    case WebCursorInfo::TypeWestResize:
      return GDK_LEFT_SIDE;
    case WebCursorInfo::TypeNorthSouthResize:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeEastWestResize:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeNorthEastSouthWestResize:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeNorthWestSouthEastResize:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeColumnResize:
      return GDK_SB_H_DOUBLE_ARROW;  // TODO(evanm): is this correct?
    case WebCursorInfo::TypeRowResize:
      return GDK_SB_V_DOUBLE_ARROW;  // TODO(evanm): is this correct?
    case WebCursorInfo::TypeMiddlePanning:
      return GDK_FLEUR;
    case WebCursorInfo::TypeEastPanning:
      return GDK_SB_RIGHT_ARROW;
    case WebCursorInfo::TypeNorthPanning:
      return GDK_SB_UP_ARROW;
    case WebCursorInfo::TypeNorthEastPanning:
      return GDK_TOP_RIGHT_CORNER;
    case WebCursorInfo::TypeNorthWestPanning:
      return GDK_TOP_LEFT_CORNER;
    case WebCursorInfo::TypeSouthPanning:
      return GDK_SB_DOWN_ARROW;
    case WebCursorInfo::TypeSouthEastPanning:
      return GDK_BOTTOM_RIGHT_CORNER;
    case WebCursorInfo::TypeSouthWestPanning:
      return GDK_BOTTOM_LEFT_CORNER;
    case WebCursorInfo::TypeWestPanning:
      return GDK_SB_LEFT_ARROW;
    case WebCursorInfo::TypeMove:
      return GDK_FLEUR;
    case WebCursorInfo::TypeVerticalText:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeCell:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeContextMenu:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeAlias:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeProgress:
      return GDK_WATCH;
    case WebCursorInfo::TypeNoDrop:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeCopy:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeNone:
// See comment above |GetInvisibleCustomCursor()|.
#if !GTK_CHECK_VERSION(2, 16, 0)
      return GDK_CURSOR_IS_PIXMAP;
#else
      return GDK_BLANK_CURSOR;
#endif
    case WebCursorInfo::TypeNotAllowed:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeZoomIn:
    case WebCursorInfo::TypeZoomOut:
    case WebCursorInfo::TypeCustom:
      return GDK_CURSOR_IS_PIXMAP;
  }
  NOTREACHED();
  return GDK_LAST_CURSOR;
}

GdkCursor* WebCursor::GetCustomCursor() const {
  switch (type_) {
// See comment above |GetInvisibleCustomCursor()|.
#if !GTK_CHECK_VERSION(2, 16, 0)
    case WebCursorInfo::TypeNone:
      return GetInvisibleCustomCursor();
#endif
    case WebCursorInfo::TypeZoomIn:
      return GetInlineCustomCursor(CustomCursorZoomIn);
    case WebCursorInfo::TypeZoomOut:
      return GetInlineCustomCursor(CustomCursorZoomOut);
  }

  if (type_ != WebCursorInfo::TypeCustom) {
    NOTREACHED();
    return NULL;
  }

  SkBitmap bitmap;
  bitmap.setConfig(SkBitmap::kARGB_8888_Config,
                   custom_size_.width(), custom_size_.height());
  bitmap.allocPixels();
  memcpy(bitmap.getAddr32(0, 0), custom_data_.data(), custom_data_.size());

  GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&bitmap);
  GdkCursor* cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(),
                                                 pixbuf,
                                                 hotspot_.x(),
                                                 hotspot_.y());

  gdk_pixbuf_unref(pixbuf);

  return cursor;
}

void WebCursor::InitPlatformData() {
  return;
}

bool WebCursor::SerializePlatformData(Pickle* pickle) const {
  return true;
}

bool WebCursor::DeserializePlatformData(const Pickle* pickle, void** iter) {
  return true;
}

bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
  return true;
}

void WebCursor::CleanupPlatformData() {
  return;
}

void WebCursor::CopyPlatformData(const WebCursor& other) {
  return;
}
<|endoftext|>


<commit_before>// Copyright (c) 2016, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of hpp-core.
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core. If not, see <http://www.gnu.org/licenses/>.

#include <hpp/core/relative-motion.hh>

#include <hpp/model/device.hh>
#include <hpp/model/joint.hh>

#include <hpp/constraints/relative-transformation.hh>

#include <hpp/core/constraint-set.hh>
#include <hpp/core/config-projector.hh>
#include <hpp/core/locked-joint.hh>

namespace hpp {
  namespace core {
    namespace {
      inline void symSet (RelativeMotion::matrix_type& m, size_type i0, size_type i1, RelativeMotion::RelativeMotionType t)
      {
        m(i0,i1) = m(i1,i0) = t;
      }

      inline JointPtr_t getNonAnchorParent (const JointPtr_t j)
      {
        JointPtr_t parent = j;
        // Find the closest non-fixed parent in the kinematic chain
        while (
            ((parent = parent->parentJoint()) != NULL)
            && parent->numberDof() == 0) {}
        return parent;
      }

      inline size_type index (const JointPtr_t j, const size_type& idIfNull)
      {
        if (j == NULL) return idIfNull;
        else return j->rankInVelocity();
      }
    }

    RelativeMotion::matrix_type RelativeMotion::matrix (const DevicePtr_t& dev)
    {
      assert (dev);
      const size_type N = dev->numberDof () + 1;
      matrix_type matrix (N, N);
      matrix.setConstant (Unconstrained);
      matrix.diagonal().setConstant(Constrained);
      return matrix;
    }

    void RelativeMotion::fromConstraint (matrix_type& matrix,
        const DevicePtr_t& robot,
        const ConstraintSetPtr_t& c)
    {
      using constraints::RelativeTransformation;
      using constraints::RelativeTransformationPtr_t;
      assert (robot);
      assert (c);

      const size_type N = robot->numberDof () + 1;
      if (matrix.rows() != N || matrix.cols() != N)
        throw std::invalid_argument ("Wrong RelativeMotion::matrix_type size");

      ConfigProjectorPtr_t proj = c->configProjector();
      if (!proj) return;

      // Loop over the LockedJoint
      const LockedJoints_t& lj = proj->lockedJoints ();
      for (LockedJoints_t::const_iterator it = lj.begin ();
          it != lj.end (); ++it) {
        JointPtr_t j;
        try {
          // Extra dofs and partial locked joints have a name that won't be
          // recognized by Device::getJointByName. So they can be filtered
          // this way.
          j = robot->getJointByName ((*it)->jointName());
        } catch (const std::runtime_error& e) {
          hppDout (info, "Joint not found:" << e.what ());
          continue;
        }
        bool cstRHS = (*it)->comparisonType()->constantRightHandSide();

        const size_type i1 = index(j, N-1),
                        i2 = index(getNonAnchorParent(j),N-1);
        recurseSetRelMotion (matrix, i1, i2, (cstRHS ? Constrained : Parameterized));
      }

      // Loop over the DifferentiableFunction
      const NumericalConstraints_t& ncs = proj->numericalConstraints ();
      for (NumericalConstraints_t::const_iterator _ncs = ncs.begin();
          _ncs != ncs.end(); ++_ncs) {
        const NumericalConstraint& nc = **_ncs;
        if (nc.comparisonType()->constantRightHandSide()) {
          RelativeTransformationPtr_t rt =
            HPP_DYNAMIC_PTR_CAST(RelativeTransformation,
                nc.functionPtr());
          if (!rt && rt->outputSize() != 6) continue;
          const size_type i1 = index(rt->joint1(), N-1),
                          i2 = index(rt->joint2(), N-1);

          bool cstRHS = nc.comparisonType()->constantRightHandSide();
          recurseSetRelMotion (matrix, i1, i2, (cstRHS ? Constrained : Parameterized));
        }
      }
    }

    void RelativeMotion::recurseSetRelMotion(matrix_type& matrix,
        const size_type& i1, const size_type& i2,
        const RelativeMotion::RelativeMotionType& type)
    {
      bool param = (type == Parameterized);
      RelativeMotionType t = Unconstrained;
      if (type == Unconstrained) return;
      symSet(matrix, i1, i2, type);

      // i1 to i3
      for (size_type i3 = 0; i3 < matrix.rows(); ++i3) {
        if (i3 == i1) continue;
        if (i3 == i2) continue;
        if (matrix(i2,i3) != Unconstrained) {
          t = (!param && matrix(i2,i3) == Constrained) ? Constrained : Parameterized;
          symSet(matrix, i1, i3, t);
        }
      }
      for (size_type i0 = 0; i0 < matrix.rows(); ++i0) {
        if (i0 == i2) continue;
        if (i0 == i1) continue;
        // i0 to i2
        if (matrix(i0,i1) != Unconstrained) {
          t = (!param && matrix(i0,i1) == Constrained) ? Constrained : Parameterized;
          symSet (matrix, i0, i2 ,t);
        }

        // from i0 to i3
        if (matrix(i0,i1) == Unconstrained) continue;
        for (size_type i3 = 0; i3 < matrix.rows(); ++i3) {
          if (i3 == i2) continue;
          if (i3 == i1) continue;
          if (i3 == i0) continue;
          if (matrix(i2,i3) == Unconstrained) continue;
          t = (!param && matrix(i0,i1) == Constrained && matrix(i2,i3) == Constrained)
            ? Constrained : Parameterized;
          symSet (matrix, i0, i3, t);
        }
      }
    }
  } // namespace core
} // namespace hpp
<commit_msg>Fix bug in RelativeMotion matrix computation<commit_after>// Copyright (c) 2016, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of hpp-core.
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core. If not, see <http://www.gnu.org/licenses/>.

#include <hpp/core/relative-motion.hh>

#include <hpp/model/device.hh>
#include <hpp/model/joint.hh>

#include <hpp/constraints/relative-transformation.hh>

#include <hpp/core/constraint-set.hh>
#include <hpp/core/config-projector.hh>
#include <hpp/core/locked-joint.hh>

namespace hpp {
  namespace core {
    namespace {
      inline void symSet (RelativeMotion::matrix_type& m, size_type i0, size_type i1, RelativeMotion::RelativeMotionType t)
      {
        m(i0,i1) = m(i1,i0) = t;
      }

      inline JointPtr_t getNonAnchorParent (const JointPtr_t j)
      {
        JointPtr_t parent = j;
        // Find the closest non-fixed parent in the kinematic chain
        while (
            ((parent = parent->parentJoint()) != NULL)
            && parent->numberDof() == 0) {}
        return parent;
      }

      inline size_type index (const JointPtr_t j, const size_type& idIfNull)
      {
        if (j == NULL) return idIfNull;
        else return j->rankInVelocity();
      }
    }

    RelativeMotion::matrix_type RelativeMotion::matrix (const DevicePtr_t& dev)
    {
      assert (dev);
      const size_type N = dev->numberDof () + 1;
      matrix_type matrix (N, N);
      matrix.setConstant (Unconstrained);
      matrix.diagonal().setConstant(Constrained);
      return matrix;
    }

    void RelativeMotion::fromConstraint (matrix_type& matrix,
        const DevicePtr_t& robot,
        const ConstraintSetPtr_t& c)
    {
      using constraints::RelativeTransformation;
      using constraints::RelativeTransformationPtr_t;
      assert (robot);
      assert (c);

      const size_type N = robot->numberDof () + 1;
      if (matrix.rows() != N || matrix.cols() != N)
        throw std::invalid_argument ("Wrong RelativeMotion::matrix_type size");

      ConfigProjectorPtr_t proj = c->configProjector();
      if (!proj) return;

      // Loop over the LockedJoint
      const LockedJoints_t& lj = proj->lockedJoints ();
      for (LockedJoints_t::const_iterator it = lj.begin ();
          it != lj.end (); ++it) {
        JointPtr_t j;
        try {
          // Extra dofs and partial locked joints have a name that won't be
          // recognized by Device::getJointByName. So they can be filtered
          // this way.
          j = robot->getJointByName ((*it)->jointName());
        } catch (const std::runtime_error& e) {
          hppDout (info, "Joint not found:" << e.what ());
          continue;
        }
        bool cstRHS = (*it)->comparisonType()->constantRightHandSide();

        const size_type i1 = index(j, N-1),
                        i2 = index(getNonAnchorParent(j),N-1);
        recurseSetRelMotion (matrix, i1, i2, (cstRHS ? Constrained : Parameterized));
      }

      // Loop over the DifferentiableFunction
      const NumericalConstraints_t& ncs = proj->numericalConstraints ();
      for (NumericalConstraints_t::const_iterator _ncs = ncs.begin();
          _ncs != ncs.end(); ++_ncs) {
        const NumericalConstraint& nc = **_ncs;
        if (nc.comparisonType()->constantRightHandSide()) {
          RelativeTransformationPtr_t rt =
            HPP_DYNAMIC_PTR_CAST(RelativeTransformation,
                nc.functionPtr());
          if (!rt || rt->outputSize() != 6) continue;
          const size_type i1 = index(rt->joint1(), N-1),
                          i2 = index(rt->joint2(), N-1);

          bool cstRHS = nc.comparisonType()->constantRightHandSide();
          recurseSetRelMotion (matrix, i1, i2, (cstRHS ? Constrained : Parameterized));
        }
      }
    }

    void RelativeMotion::recurseSetRelMotion(matrix_type& matrix,
        const size_type& i1, const size_type& i2,
        const RelativeMotion::RelativeMotionType& type)
    {
      bool param = (type == Parameterized);
      RelativeMotionType t = Unconstrained;
      if (type == Unconstrained) return;
      symSet(matrix, i1, i2, type);

      // i1 to i3
      for (size_type i3 = 0; i3 < matrix.rows(); ++i3) {
        if (i3 == i1) continue;
        if (i3 == i2) continue;
        if (matrix(i2,i3) != Unconstrained) {
          t = (!param && matrix(i2,i3) == Constrained) ? Constrained : Parameterized;
          symSet(matrix, i1, i3, t);
        }
      }
      for (size_type i0 = 0; i0 < matrix.rows(); ++i0) {
        if (i0 == i2) continue;
        if (i0 == i1) continue;
        // i0 to i2
        if (matrix(i0,i1) != Unconstrained) {
          t = (!param && matrix(i0,i1) == Constrained) ? Constrained : Parameterized;
          symSet (matrix, i0, i2 ,t);
        }

        // from i0 to i3
        if (matrix(i0,i1) == Unconstrained) continue;
        for (size_type i3 = 0; i3 < matrix.rows(); ++i3) {
          if (i3 == i2) continue;
          if (i3 == i1) continue;
          if (i3 == i0) continue;
          if (matrix(i2,i3) == Unconstrained) continue;
          t = (!param && matrix(i0,i1) == Constrained && matrix(i2,i3) == Constrained)
            ? Constrained : Parameterized;
          symSet (matrix, i0, i3, t);
        }
      }
    }
  } // namespace core
} // namespace hpp
<|endoftext|>


<commit_before>/*
 * This file is part of the IAN project - https://github.com/Meoo/IAN
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
// Generated file
#pragma once

#include <functional>
#include <map>
#include <mutex>
#include <type_traits>

namespace @RPC_NAMESPACE@
{

namespace impl
{
// http://en.cppreference.com/w/cpp/types/disjunction
// Remove when C++17
template<class...>
struct Disjunction : std::false_type {};
template<class B1>
struct Disjunction<B1> : B1 {};
template<class B1, class... Bn>
struct Disjunction<B1, Bn...>
    : std::conditional_t<bool(B1::value), B1, Disjunction<Bn...>> {};

template<class If, class... Interfaces>
using ContainsIf = impl::Disjunction<std::is_same<If, Interfaces>...>;
}

// Return callback

template<class Base, class R, typename T>
class RpcReturn
{
 public:
  explicit inline RpcReturn(Base * ptr) : ptr_(ptr) {}
  inline RpcReturn(RpcReturn && other) : ptr_(other.ptr_), rpc_id_(other.rpc_id_)
  {
    other.ptr_ = nullptr;
  }
  RpcReturn(const RpcReturn &) = delete;
  RpcReturn & operator=(const RpcReturn &) = delete;

  inline ~RpcReturn()
  {
    if (ptr_)
      error(0, "RpcReturn object dropped");
  }

  inline void operator()(flatbuffers::FlatBufferBuilder & builder, flatbuffers::Offset<T> data)
  {
    if (!ptr_)
      return;
    auto rpc_rep = CreateRpcReply(builder, rpc_id_, RpcReplyUTraits<T>::enum_value, data.Union());
    static_cast<R *>(ptr_)->emit_rpc_reply(builder, rpc_rep);
    ptr_ = nullptr;
  }

  inline void error(std::uint32_t error_code, const char * error_str)
  {
    if (!ptr_)
      return;
    flatbuffers::FlatBufferBuilder builder;
    auto err     = CreateRpcErrorDirect(builder, error_code, error_str);
    auto rpc_rep = CreateRpcReply(builder, rpc_id_, RpcReplyU::RpcReplyU_RpcError, err.Union());
    static_cast<R *>(ptr_)->emit_rpc_reply(builder, rpc_rep);
    ptr_ = nullptr;
  }

 private:
  Base * ptr_;
  uint32_t rpc_id_ = 0;
};

// Result invoker

class RpcResultInvoker
{
 public:
  RpcResultInvoker() : expected_reply_(RpcReplyU::RpcReplyU_NONE) {}
  RpcResultInvoker(RpcResultInvoker && other)
      : expected_reply_(other.expected_reply_), callback_(other.callback_)
  {
    other.expected_reply_ = RpcReplyU::RpcReplyU_NONE;
  }
  RpcResultInvoker(const RpcResultInvoker &) = delete;
  RpcResultInvoker & operator=(const RpcResultInvoker &) = delete;

  template<typename F>
  RpcResultInvoker(RpcReplyU expected_reply, F && callback)
      : expected_reply_(expected_reply), callback_(std::forward<F>(callback))
  {
  }

  void invoke(const RpcReply & reply)
  {
    if (reply.data_type() == RpcReplyU::RpcReplyU_RpcError)
    {
      callback_(nullptr, reply.data_as_RpcError());
      return;
    }

    if (reply.data_type() != expected_reply_)
    {
      // Should never happen
      flatbuffers::FlatBufferBuilder builder;
      auto rep = CreateRpcErrorDirect(builder, 0, "Received invalid result");
      auto err = flatbuffers::GetRoot<RpcError>(builder.GetBufferPointer());
      callback_(nullptr, err);
      return;
    }

    callback_(reply.data(), nullptr);
  }

 private:
  RpcReplyU expected_reply_;
  std::function<void(const void *, const RpcError *)> callback_;
};

// { Interfaces

@RPC_HPP_INTERFACES@// } Interfaces

// Receiver

template<class Base, template<class, bool> class... Interfaces>
class RpcReceiver : public Interfaces<Base, true>...
{
protected:
  inline bool dispatch_rpc_request(const RpcRequest & request)
  {
    switch (request.data_type())
    {
@RPC_HPP_REQUEST_SWITCH@
    default: return false;
    }
  }
private:
@RPC_HPP_REQUEST_DISPATCHERS@
};

// Sender

template<class Base, template<class, bool> class... Interfaces>
class RpcSender : public Interfaces<Base, false>...
{
protected:
  std::uint32_t register_rpc_return_callback(RpcResultInvoker callback) final
  {
    std::unique_lock<std::mutex> lock(mutex_);
    std::uint32_t id = next_id_++;
    result_callbacks_.emplace(std::make_pair(id, std::move(callback)));
    return id;
  }
  inline bool dispatch_rpc_reply(const RpcReply & reply)
  {
    RpcResultInvoker cb;
    {
      std::unique_lock<std::mutex> lock(mutex_);
      auto it = result_callbacks_.find(reply.id());
      if (it == result_callbacks_.end())
        return false;
      cb = std::move(it->second);
      result_callbacks_.erase(it);
    }
    cb.invoke(reply);
  }
private:
  std::mutex mutex_;
  std::uint32_t next_id_ = 1;
  std::map<std::uint32_t, RpcResultInvoker> result_callbacks_;
};

} // namespace @RPC_NAMESPACE@
<commit_msg>Rpc: add move assignment to RpcReturn & RpcResultInvoker<commit_after>/*
 * This file is part of the IAN project - https://github.com/Meoo/IAN
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
// Generated file
#pragma once

#include <functional>
#include <map>
#include <mutex>
#include <type_traits>

namespace @RPC_NAMESPACE@
{

namespace impl
{
// http://en.cppreference.com/w/cpp/types/disjunction
// Remove when C++17
template<class...>
struct Disjunction : std::false_type {};
template<class B1>
struct Disjunction<B1> : B1 {};
template<class B1, class... Bn>
struct Disjunction<B1, Bn...>
    : std::conditional_t<bool(B1::value), B1, Disjunction<Bn...>> {};

template<class If, class... Interfaces>
using ContainsIf = impl::Disjunction<std::is_same<If, Interfaces>...>;
}

// Return callback

template<class Base, class R, typename T>
class RpcReturn
{
 public:
  explicit inline RpcReturn(Base * ptr) : ptr_(ptr) {}
  inline RpcReturn(RpcReturn && other) : ptr_(other.ptr_), rpc_id_(other.rpc_id_)
  {
    other.ptr_ = nullptr;
  }
  RpcReturn(const RpcReturn &) = delete;
  RpcReturn & operator=(const RpcReturn &) = delete;
  RpcReturn & operator=(RpcReturn && other)
  {
    ptr_ = other.ptr_;
    rpc_id_ = other.rpc_id_;
    other.ptr_ = nullptr;
    return *this;
  }

  inline ~RpcReturn()
  {
    if (ptr_)
      error(0, "RpcReturn object dropped");
  }

  inline void operator()(flatbuffers::FlatBufferBuilder & builder, flatbuffers::Offset<T> data)
  {
    if (!ptr_)
      return;
    auto rpc_rep = CreateRpcReply(builder, rpc_id_, RpcReplyUTraits<T>::enum_value, data.Union());
    static_cast<R *>(ptr_)->emit_rpc_reply(builder, rpc_rep);
    ptr_ = nullptr;
  }

  inline void error(std::uint32_t error_code, const char * error_str)
  {
    if (!ptr_)
      return;
    flatbuffers::FlatBufferBuilder builder;
    auto err     = CreateRpcErrorDirect(builder, error_code, error_str);
    auto rpc_rep = CreateRpcReply(builder, rpc_id_, RpcReplyU::RpcReplyU_RpcError, err.Union());
    static_cast<R *>(ptr_)->emit_rpc_reply(builder, rpc_rep);
    ptr_ = nullptr;
  }

 private:
  Base * ptr_;
  uint32_t rpc_id_ = 0;
};

// Result invoker

class RpcResultInvoker
{
 public:
  RpcResultInvoker() : expected_reply_(RpcReplyU::RpcReplyU_NONE) {}
  RpcResultInvoker(RpcResultInvoker && other)
      : expected_reply_(other.expected_reply_), callback_(other.callback_)
  {
    other.expected_reply_ = RpcReplyU::RpcReplyU_NONE;
  }
  RpcResultInvoker(const RpcResultInvoker &) = delete;
  RpcResultInvoker & operator=(const RpcResultInvoker &) = delete;
  RpcResultInvoker & operator=(RpcResultInvoker && other)
  {
    expected_reply_ = other.expected_reply_;
    callback_ = other.callback_;
    other.expected_reply_ = RpcReplyU::RpcReplyU_NONE;
    return *this;
  }

  template<typename F>
  RpcResultInvoker(RpcReplyU expected_reply, F && callback)
      : expected_reply_(expected_reply), callback_(std::forward<F>(callback))
  {
  }

  void invoke(const RpcReply & reply)
  {
    if (reply.data_type() == RpcReplyU::RpcReplyU_RpcError)
    {
      callback_(nullptr, reply.data_as_RpcError());
      return;
    }

    if (reply.data_type() != expected_reply_)
    {
      // Should never happen
      flatbuffers::FlatBufferBuilder builder;
      auto rep = CreateRpcErrorDirect(builder, 0, "Received invalid result");
      auto err = flatbuffers::GetRoot<RpcError>(builder.GetBufferPointer());
      callback_(nullptr, err);
      return;
    }

    callback_(reply.data(), nullptr);
  }

 private:
  RpcReplyU expected_reply_;
  std::function<void(const void *, const RpcError *)> callback_;
};

// { Interfaces

@RPC_HPP_INTERFACES@// } Interfaces

// Receiver

template<class Base, template<class, bool> class... Interfaces>
class RpcReceiver : public Interfaces<Base, true>...
{
protected:
  inline bool dispatch_rpc_request(const RpcRequest & request)
  {
    switch (request.data_type())
    {
@RPC_HPP_REQUEST_SWITCH@
    default: return false;
    }
  }
private:
@RPC_HPP_REQUEST_DISPATCHERS@
};

// Sender

template<class Base, template<class, bool> class... Interfaces>
class RpcSender : public Interfaces<Base, false>...
{
protected:
  std::uint32_t register_rpc_return_callback(RpcResultInvoker callback) final
  {
    std::unique_lock<std::mutex> lock(mutex_);
    std::uint32_t id = next_id_++;
    result_callbacks_.emplace(std::make_pair(id, std::move(callback)));
    return id;
  }
  inline bool dispatch_rpc_reply(const RpcReply & reply)
  {
    RpcResultInvoker cb;
    {
      std::unique_lock<std::mutex> lock(mutex_);
      auto it = result_callbacks_.find(reply.id());
      if (it == result_callbacks_.end())
        return false;
      cb = std::move(it->second);
      result_callbacks_.erase(it);
    }
    cb.invoke(reply);
  }
private:
  std::mutex mutex_;
  std::uint32_t next_id_ = 1;
  std::map<std::uint32_t, RpcResultInvoker> result_callbacks_;
};

} // namespace @RPC_NAMESPACE@
<|endoftext|>