1f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SampleCode.h" 2f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkView.h" 3f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkCanvas.h" 4f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkGPipe.h" 5f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkSockets.h" 6f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkNetPipeController.h" 7f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkCornerPathEffect.h" 8f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkOSMenu.h" 9f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include <map> 10ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com 11ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com/** 12ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * Drawing Server 13ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * 14d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * This simple drawing server can accept connections from multiple drawing 15d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * clients simultaneously. It accumulates drawing data from each client each 16ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * frame, stores it in the appropriate place, and then broadcasts incremental 17ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * changes back to all the clients. Each logical packet, meaning one brush 18ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * stoke in this case can be of two types, append and replace. Append types are 19ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * completed strokes ready to be stored in the fData queue and will no longer be 20d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * modified. Replace types are drawing operations that are still in progress on 21d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * the client side, so they are appended to fBuffer. The location and size of 22ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * the buffered data for each client is stored in a map and updated properly. 23ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * Each time a new replace drawing call is received from a client, its previous 24ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * buffered data is discarded. 25ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * Since the Server keeps all the complete drawing data and the latest buffered 26ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * data, it's able to switch between vector and bitmap drawing 27ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com */ 28ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com 29f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comclass DrawingServerView : public SampleView { 30f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.compublic: 31d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com DrawingServerView(){ 32f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fServer = new SkTCPServer(40000); 33f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fServer->suspendWrite(); 34f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fTotalBytesRead = fTotalBytesWritten = 0; 35f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fVector = true; 36f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 37f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com ~DrawingServerView() { 38f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com delete fServer; 39f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fData.reset(); 40f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fBuffer.reset(); 41f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fClientMap.clear(); 42f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 43d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 44f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com virtual void requestMenu(SkOSMenu* menu) { 45f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com menu->setTitle("Drawing Server"); 46f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com menu->appendAction("Clear", this->getSinkID()); 47f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com menu->appendSwitch("Vector", "Vector", this->getSinkID(), fVector); 48f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 49d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 50f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comprotected: 51d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com static void readData(int cid, const void* data, size_t size, 52f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkSocket::DataType type, void* context) { 53f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com DrawingServerView* view = (DrawingServerView*)context; 54f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com view->onRead(cid, data, size, type); 55f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 56d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 57f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com void onRead(int cid, const void* data, size_t size, SkSocket::DataType type) { 58f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com if (NULL == data && size <= 0) 59f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com return; 60d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 61f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com ClientState* cs; 62f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com std::map<int, ClientState*>::iterator it = fClientMap.find(cid); 63f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com if (it == fClientMap.end()) { //New client 64f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com cs = new ClientState; 65f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com cs->bufferBase = 0; 66f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com cs->bufferSize = 0; 67f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fClientMap[cid] = cs; 68f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 69f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com else { 70f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com cs = it->second; 71f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 72d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 73f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com if (type == SkSocket::kPipeReplace_type) { 74f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fBuffer.remove(cs->bufferBase, cs->bufferSize); 75d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 76f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com for (it = fClientMap.begin(); it != fClientMap.end(); ++it) { 77f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com if (cid == it->first) 78f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com continue; 79f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com else { 80f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com if (it->second->bufferBase > cs->bufferBase) { 81f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com it->second->bufferBase -= cs->bufferSize; 82f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkASSERT(it->second->bufferBase >= 0); 83f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 84f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 85f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 86d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 87f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com cs->bufferBase = fBuffer.count(); 88f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com cs->bufferSize = size; 89f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fBuffer.append(size, (const char*)data); 90f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 91f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com else if (type == SkSocket::kPipeAppend_type) { 92f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fData.append(size, (const char*)data); 93f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fServer->resumeWrite(); 94f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fServer->writePacket(fData.begin() + fTotalBytesWritten, 95f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fData.count() - fTotalBytesWritten, 96f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkSocket::kPipeAppend_type); 97f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fTotalBytesWritten = fData.count(); 98f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fServer->suspendWrite(); 99f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 100f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com else { 101f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com //other types of data 102f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 103f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 104d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 105f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com bool onQuery(SkEvent* evt) { 106f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com if (SampleCode::TitleQ(*evt)) { 107f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SampleCode::TitleR(evt, "Drawing Server"); 108f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com return true; 109f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 110f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com return this->INHERITED::onQuery(evt); 111f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 112d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 113f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com bool onEvent(const SkEvent& evt) { 114ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com if (SkOSMenu::FindAction(evt, "Clear")) { 115f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com this->clear(); 116f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com return true; 117f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 118ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com if (SkOSMenu::FindSwitchState(evt, "Vector", &fVector)) { 119f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com this->clearBitmap(); 120f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com return true; 121f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 122f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com return this->INHERITED::onEvent(evt); 123f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 124d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 125d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 126f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com virtual void onDrawContent(SkCanvas* canvas) { 127f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com if (fCurrMatrix != canvas->getTotalMatrix()) { 128f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fTotalBytesRead = 0; 129f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fCurrMatrix = canvas->getTotalMatrix(); 130f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 131f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com 132f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fServer->acceptConnections(); 133f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com if (fServer->readPacket(readData, this) > 0) { 134f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fServer->resumeWrite(); 135f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 136f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com else { 137f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fServer->suspendWrite(); 138f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 139d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 140f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com size_t bytesRead; 141ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com SkGPipeReader::Status stat; 142f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkCanvas bufferCanvas(fBase); 143f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkCanvas* tempCanvas; 144f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com while (fTotalBytesRead < fData.count()) { 145ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com if (fVector) { 146f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com tempCanvas = canvas; 147ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com } else { 148f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com tempCanvas = &bufferCanvas; 149ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com } 150f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkGPipeReader reader(tempCanvas); 151ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com stat = reader.playback(fData.begin() + fTotalBytesRead, 152ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com fData.count() - fTotalBytesRead, 153ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com &bytesRead); 154f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkASSERT(SkGPipeReader::kError_Status != stat); 155f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fTotalBytesRead += bytesRead; 156f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 157ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com if (fVector) { 158f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fTotalBytesRead = 0; 159ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com } else { 160f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com canvas->drawBitmap(fBase, 0, 0, NULL); 161ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com } 162d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 163f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com size_t totalBytesRead = 0; 164f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com while (totalBytesRead < fBuffer.count()) { 165f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkGPipeReader reader(canvas); 166ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com stat = reader.playback(fBuffer.begin() + totalBytesRead, 167ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com fBuffer.count() - totalBytesRead, 168ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com &bytesRead); 169ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com SkASSERT(SkGPipeReader::kError_Status != stat); 170f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com totalBytesRead += bytesRead; 171f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 172d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 173d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com fServer->writePacket(fBuffer.begin(), fBuffer.count(), 174f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkSocket::kPipeReplace_type); 175f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com 176f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com this->inval(NULL); 177f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 178d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 179f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com virtual void onSizeChange() { 180f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com this->INHERITED::onSizeChange(); 181d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com fBase.setConfig(SkBitmap::kARGB_8888_Config, 182d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com this->width(), 183ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com this->height()); 184f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fBase.allocPixels(NULL); 185f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com this->clearBitmap(); 186f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 187d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 188f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comprivate: 189f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com void clear() { 190f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fData.reset(); 191f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fBuffer.reset(); 192f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fTotalBytesRead = fTotalBytesWritten = 0; 193f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fClientMap.clear(); 194f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com this->clearBitmap(); 195f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 196f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com void clearBitmap() { 197f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fTotalBytesRead = 0; 198f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com fBase.eraseColor(fBGColor); 199f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com } 200d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 201f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com struct ClientState { 202f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com int bufferBase; 203f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com int bufferSize; 204f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com }; 205d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 206f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com std::map<int, ClientState*> fClientMap; 207f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkTDArray<char> fData; 208f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkTDArray<char> fBuffer; 209f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com size_t fTotalBytesRead; 210f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com size_t fTotalBytesWritten; 211f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkMatrix fCurrMatrix; 212f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkBitmap fBase; 213f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com bool fVector; 214f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com SkTCPServer* fServer; 215f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com typedef SampleView INHERITED; 216f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com}; 217f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com 218f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com 219f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com/////////////////////////////////////////////////////////////////////////////// 220f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com 221f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comstatic SkView* MyFactory() { return new DrawingServerView; } 222f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comstatic SkViewRegister reg(MyFactory); 223