Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Speed improvements

  • Loading branch information...
commit 82b7841d95341f614b649ad8d79436bd825fd495 1 parent 7ee7541
@comex authored
View
2  Player2/Classes/FlashViewController.h
@@ -19,7 +19,7 @@
}
@property (retain) Server *server;
- (void)useSurface:(IOSurfaceRef)sfc;
-- (void)displaySync;
+- (void)displaySyncInRect:(CGRect *)rect;
- (CGSize)movieSize;
- (void)diedWithError:(NSString *)error;
View
2  Player2/Classes/FlashViewController.m
@@ -95,7 +95,7 @@ - (NSURL *)baseURL {
return nil;
}
-- (void)displaySync {
+- (void)displaySyncInRect:(CGRect *)rect {
CGImageRef image = CGImageCreate(
IOSurfaceGetWidth(sfc),
IOSurfaceGetHeight(sfc),
View
2  Player2/Classes/PluginFlashView.h
@@ -22,7 +22,7 @@
@property (retain) Server *server;
- (void)useSurface:(IOSurfaceRef)sfc;
-- (void)displaySync;
+- (void)displaySyncInRect:(CGRect *)rect;
- (CGSize)movieSize;
- (void)diedWithError:(NSString *)error;
View
11 Player2/Classes/PluginFlashView.m
@@ -99,10 +99,11 @@ - (id)evaluateWebScript:(NSString *)script {
- (void)useSurface:(IOSurfaceRef)sfc_ {
if(sfc) CFRelease(sfc);
sfc = sfc_;
+ self.layer.contents = (id) sfc;
}
-- (void)displaySync {
+- (void)displaySyncInRect:(CGRect *)rect {
if(!sfc || !IOSurfaceGetWidth(sfc)) return;
/* CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, IOSurfaceGetBaseAddress(sfc), IOSurfaceGetAllocSize(sfc), NULL);
CGImageRef image = CGImageCreate(
@@ -122,8 +123,12 @@ - (void)displaySync {
CFRelease(data);
self.layer.contents = (id) image;
CFRelease(image);*/
- self.layer.contents = (id) sfc;
- self.layer.opacity = self.layer.opacity == 1.0 ? 0.9999 : 1.0;
+ //self.layer.contents = (id) sfc;
+ if(rect->size.width) {
+ [self.layer setNeedsDisplayInRect:*rect];
+ } else {
+ [self.layer setNeedsDisplay];
+ }
}
- (NSDictionary *)paramsDict {
View
6 Player2/server.m
@@ -19,6 +19,7 @@
#import <Foundation/Foundation.h>
#include <unistd.h>
#include <notify.h>
+#include <QuartzCore/QuartzCore.h>
#define BORING 0
#define FOOD_ROOT "/var/mobile/"
@@ -208,9 +209,10 @@ int use_surface(int rpc_fd, int surface) {
return 0;
}
-int display_sync(int rpc_fd) {
+int display_sync(int rpc_fd, int l, int t, int r, int b) {
Server *self = get_server(rpc_fd);
- [self->delegate performSelector:@selector(displaySync)];
+ CGRect rect = CGRectMake(l, t, r-l, b-t);
+ [self->delegate performSelector:@selector(displaySyncInRect:) withObject:(id)&rect];
return 0;
}
View
10 control
@@ -0,0 +1,10 @@
+Package: frash
+Architecture: armv7
+Name: frash
+Version: 0.00
+Priority: optional
+Description: All your base are belong to us?
+Homepage: http://github.com/comex/frash
+Maintainer: comex <comexk@gmail.com>
+Section: Utilities
+
View
10 food/Makefile
@@ -1,7 +1,15 @@
export SDK := /var/sdk
all: food food_wrapper
-STUFF := -mthumb -g3 -Wreturn-type -Wall -DHAVE_MACOSX_IPC -DOS_PATH_SEPARATOR="'/'" -DHAVE_PTHREADS -DHAVE_POSIX_FILEMAP -DHAVE_LITTLE_ENDIAN -I. -I../rpc -I../utils -I../utils/libcutils -isysroot $(SDK) -arch armv7 -ffixed-r9 -Werror
+
+STUFF = -mthumb -Wreturn-type -Wall -DHAVE_MACOSX_IPC -DOS_PATH_SEPARATOR="'/'" -DHAVE_PTHREADS -DHAVE_POSIX_FILEMAP -DHAVE_LITTLE_ENDIAN -I. -I../rpc -I../utils -I../utils/libcutils -isysroot $(SDK) -arch armv7 -ffixed-r9 -Werror -Wno-uninitialized -g3 -O2
+DEBUG = 1
+
+#ifeq "$(DEBUG)" "1"
+#STUFF += -g3
+#else
+#STUFF += -O2
+#endif
%.o: %.cpp common.h ../rpc/food_rpc1.h
g++-4.2 $(STUFF) -c -o $@ $<
View
2  food/TODO
@@ -1,6 +1,4 @@
-- pthread_cond_timedwait
- invocation arguments
-- make Flash shut up when home is pressed (but Safari is not actually stopped)
- make it think it's fullscreen or otherwise fix mouse
- keyboard
- video?
View
42 food/anp.cpp
@@ -105,8 +105,8 @@ struct ANPAudioTrack {
void aqtry_(OSStatus ret, const char *name) {
if(!ret) return;
- notice("Audio error in %s:", name);
- notice("%d", (int) ret);
+ err("Audio error in %s:", name);
+ err("%d", (int) ret);
_abort();
}
#define aqtry(x) aqtry_(x, #x)
@@ -155,7 +155,7 @@ ANPAudioTrack* audiotrack_impl_newTrack(uint32_t sampleRate, // sampling rat
switch(sampleFormat) {
case kPCM16Bit_ANPSampleFormat: bits = 16; break;
case kPCM8Bit_ANPSampleFormat: bits = 8; break;
- default: _assert(false);
+ default: _abort();
}
FillOutASBDForLPCM(fmt, sampleRate, channelCount, bits, bits, false, false, false);
aqtry(AudioQueueNewOutput(&fmt, trackCallbackProc, result, NULL, NULL, 0, &result->aq));
@@ -1128,6 +1128,8 @@ void event_impl_postEvent(NPP inst, const ANPEvent* event) {
static void *temp;
static size_t temp_sz;
+static ANPRectI cur_dirty;
+static bool cur_dirty_valid;
// ANPSurfaceInterfaceV0
extern "C" void refresh_size();
@@ -1138,9 +1140,18 @@ bool surface_impl_lock(JNIEnv* env, jobject surface, ANPBitmap* bitmap, ANPRectI
}
if(temp_sz != IOSurfaceGetAllocSize(sfc)) {
if(temp) free(temp);
- temp = calloc(1, IOSurfaceGetAllocSize(sfc));
+ temp = calloc(1, IOSurfaceGetAllocSize(sfc) + 128);
//memset(temp, 0xff, IOSurfaceGetAllocSize(sfc));
temp_sz = IOSurfaceGetAllocSize(sfc);
+ dirtyRect = NULL; // it is probably invalid
+ }
+ //log("dirtyRect=%p", dirtyRect);
+ if(dirtyRect) {
+ //log("%d,%d,%d,%d", dirtyRect->left, dirtyRect->top, dirtyRect->right, dirtyRect->bottom);
+ cur_dirty_valid = true;
+ cur_dirty = *dirtyRect;
+ } else {
+ cur_dirty_valid = false;
}
bitmap->baseAddr = temp;
bitmap->format = kRGBA_8888_ANPBitmapFormat;
@@ -1152,16 +1163,33 @@ bool surface_impl_lock(JNIEnv* env, jobject surface, ANPBitmap* bitmap, ANPRectI
//#include <fcntl.h>
extern "C" void rgba_bgra_copy(void *dest, void *src, void *end);
+
void surface_impl_unlock(JNIEnv* env, jobject surface) {
notice("%s surface=%p", __func__, surface);
if(!sfc || !IOSurfaceGetWidth(sfc) || !IOSurfaceGetHeight(sfc)) return;
- void *end = (void *) ((char*)temp + IOSurfaceGetAllocSize(sfc));
- rgba_bgra_copy(IOSurfaceGetBaseAddress(sfc), temp, end);
+ if(cur_dirty_valid) {
+ int rowsize = (cur_dirty.right - cur_dirty.left) * 4;
+ int fullrowsize = IOSurfaceGetBytesPerRow(sfc);
+ int rowoffset = cur_dirty.top * fullrowsize + cur_dirty.left * 4;
+ char *start = ((char *) IOSurfaceGetBaseAddress(sfc)) + rowoffset;
+ char *tempstart = ((char *) temp) + rowoffset;
+ char *end = tempstart + rowsize;
+ for(int y = cur_dirty.top; y < cur_dirty.bottom; y++) {
+ rgba_bgra_copy((void *) start, (void *) tempstart, (void *) end);
+ start += fullrowsize;
+ tempstart += fullrowsize;
+ end += fullrowsize;
+ }
+ _assertZero(display_sync(food, cur_dirty.left, cur_dirty.top, cur_dirty.right, cur_dirty.bottom));
+ } else {
+ void *end = (void *) ((char *)temp + IOSurfaceGetAllocSize(sfc));
+ rgba_bgra_copy(IOSurfaceGetBaseAddress(sfc), temp, end);
+ _assertZero(display_sync(food, 0, 0, 0, 0));
+ }
//memcpy(IOSurfaceGetBaseAddress(sfc), temp, IOSurfaceGetAllocSize(sfc));
/*int fd = open("foo.txt", O_WRONLY | O_CREAT, 0755);
write(fd, IOSurfaceGetBaseAddress(sfc), IOSurfaceGetAllocSize(sfc));
close(fd);*/
- _assertZero(display_sync(food));
}
//
View
4 food/classes.c
@@ -191,7 +191,7 @@ jobject getAssetFileDescriptor(jclass cls, jvalue *a) {
s(descriptor, "getLength[()J]", make_a(afdGetLength));
int fd;
- log("opening %@", astName);
+ notice("opening %@", astName);
if(CFEqual(astName, CFSTR("oem.cfg"))) {
fd = oemcfg_fd;
} else {
@@ -351,7 +351,7 @@ void init_classes() {
static IOSurfaceRef make_iosurface() {
CFMutableDictionaryRef dict;
int pitch = movie_w * 4;
- int allocSize = pitch * movie_h + 64;
+ int allocSize = pitch * movie_h + 128;
int bytesPerElement = 4;
char pixelFormat[4] = {'A', 'R', 'G', 'B'};
View
9 food/common.c
@@ -5,6 +5,7 @@
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/time.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <spawn.h>
@@ -219,3 +220,11 @@ void _abort_(const char *file, int line) {
err("_abort() %s:%d", file, line);
exit(1);
}
+
+#if TIMING
+uint64_t getus() {
+ struct timeval tp;
+ gettimeofday(&tp, NULL);
+ return ((uint64_t) tp.tv_sec) * 1000000 + (uint64_t) tp.tv_usec;
+}
+#endif
View
9 food/common.h
@@ -87,7 +87,6 @@ void _abort_(const char *file, int line);
void _assert_(bool test, const char *label, const char *file, int line, const char *func);
void _assertZero_(int test, const char *label, const char *file, int line, const char *func);
-#define _abort() _abort_(__FILE__, __LINE__)
#define _assert(x) _assert_((x), #x, __FILE__, __LINE__, __func__)
#define _assertZero(x) _assertZero_((int) (x), #x, __FILE__, __LINE__, __func__)
@@ -108,4 +107,10 @@ extern int movie_w, movie_h, pending_movie_w, pending_movie_h;
#define notice(args...) logx(3, args)
#define log(args...) logx(1, args)
#define err(args...) logx(0, args)
-
+#define TIMING 1
+#if TIMING
+uint64_t getus();
+#define TIME(thing) do { uint64_t _ta = getus(); thing; uint64_t _tb = getus(); log("[%.4ld us] %s", (long int) (_tb - _ta), #thing); } while(0)
+#else
+#define TIME(thing) thing
+#endif
View
12 food/fixups/cfixups.c
@@ -49,7 +49,7 @@ int prctl(int option, unsigned long arg2, unsigned long arg3 , unsigned long arg
}
int cacheflush(char *start, char *end, int flags) {
- fprintf(stderr, "cacheflush %p %p %d\n", start, end, flags);
+ //fprintf(stderr, "cacheflush %p %p %d\n", start, end, flags);
sys_dcache_flush(start, (size_t) (end - start));
sys_icache_invalidate(start, (size_t) (end - start));
return 0;
@@ -184,22 +184,22 @@ const char *_ctype_ = _C_ctype_;
void *rmmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) {
// Linux and OSX use different values for MAP_ANON(YMOUS)
if(flags & 0x1000) {
- fprintf(stderr, "MAP_EXECUTAbLE\n");
+ //fprintf(stderr, "MAP_EXECUTAbLE\n");
flags &= ~0x1000;
}
if(flags & 0x20) {
- fprintf(stderr, "MAP_RENAME\n");
+ //fprintf(stderr, "MAP_RENAME\n");
flags &= ~0x20;
flags |= MAP_ANON;
}
void *ret = mmap(addr, len, prot, flags, fd, offset);
- fprintf(stderr, "addr:%p len:%d prot:%d flags:%x fd:%d offset:%x\n", addr, (int) len, prot, flags, fd, (int) offset);
- fprintf(stderr, "mmap ret: %p\n", ret);
+ //fprintf(stderr, "addr:%p len:%d prot:%d flags:%x fd:%d offset:%x\n", addr, (int) len, prot, flags, fd, (int) offset);
+ //fprintf(stderr, "mmap ret: %p\n", ret);
return ret;
}
int rmprotect(void *addr, size_t len, int prot) {
- fprintf(stderr, "mprotect %p (%d): %x\n", addr, (int) len, prot);
+ //fprintf(stderr, "mprotect %p (%d): %x\n", addr, (int) len, prot);
return mprotect(addr, len, prot);
}
View
BIN  food/food
Binary file not shown
View
152 food/food.c
@@ -140,65 +140,7 @@ static void do_patches() {
//*((void **) 0x0213dfdc) = stubify(logpatched, "logpatched", false);
}
-extern void fds_init();
-extern void go(void *NP_Initialize_ptr, void *JNI_OnLoad_ptr);
-
-extern void GSFontInitialize();
-
-int main(int argc, char **argv) {
- chdir(dirname(argv[0]));
- setvbuf(stdout, NULL, _IONBF, 0);
-
- char *rpcname = NULL;
-
- argc--; argv++;
- while(argc--) {
- char *p = *argv++;
- if(!strcmp(p, "-q")) {
- fclose(stdout);
- fclose(stderr);
- } else {
- _assert(p[0] != '-');
- rpcname = p;
- }
- }
-
- _assert(rpcname);
-
- GSFontInitialize(); // magic sauce; if this is not called, CTFontCreate* crashes
-
- rpc_init(rpcname);
-
- stubs_base = mmap(NULL, STUBS_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
- stubs = stubs_base;
-
- existing_stubs = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
-
- add("/usr/lib/libcrypto.dylib");
- add("/usr/lib/libssl.dylib");
- add("/usr/lib/libm.dylib");
- add("/usr/lib/libSystem.B.dylib");
- add("./libcutils.dylib");
- add("./libutils.dylib");
- add("./libgccstuff.dylib");
-
- add("./libicudata.42.1.dylib");
- add("./libicui18n.42.1.dylib");
- add("./libicuio.42.1.dylib");
- add("./libicule.42.1.dylib");
- add("./libiculx.42.1.dylib");
- add("./libicutu.42.1.dylib");
- add("./libicuuc.42.1.dylib");
-
-
- int fd = open("libflashplayer.so", O_RDONLY);
- _assert(fd > 0);
-
- fds_init();
-
- sandbox_me();
-
-
+static void base_load_elf(int fd, Elf32_Sym **symtab, int *symtab_size, void ***init_array, Elf32_Word *init_array_size, char **strtab) {
Elf32_Ehdr ehdr;
xread(fd, &ehdr, sizeof(ehdr));
@@ -254,9 +196,8 @@ int main(int argc, char **argv) {
}
_assert(ehdr.e_shentsize >= sizeof(Elf32_Shdr));
- Elf32_Sym *symtab = NULL;
- Elf32_Word symtab_size;
- char *strtab = NULL;
+ *symtab = NULL;
+ *strtab = NULL;
Elf32_Word shstrtab = 0;
lseek(fd, ehdr.e_shoff, SEEK_SET);
@@ -265,24 +206,23 @@ int main(int argc, char **argv) {
Elf32_Shdr *sh = (Elf32_Shdr *) malloc(ehdr.e_shentsize);
xread(fd, sh, ehdr.e_shentsize);
if(sh->sh_type == SHT_DYNSYM) {
- symtab = v2v(sh->sh_addr);
- symtab_size = sh->sh_size;
+ *symtab = v2v(sh->sh_addr);
+ *symtab_size = sh->sh_size;
} else if(sh->sh_type == SHT_STRTAB) {
- if(strtab) {
+ if(*strtab) {
shstrtab = sh->sh_offset;
} else {
- strtab = v2v(sh->sh_addr);
+ *strtab = v2v(sh->sh_addr);
}
}
free(sh);
}
- _assert(symtab);
- _assert(strtab);
+ _assert(*symtab);
+ _assert(*strtab);
_assert(shstrtab);
- void **init_array = NULL;
- Elf32_Word init_array_size;
+ *init_array = NULL;
lseek(fd, ehdr.e_shoff, SEEK_SET);
shnum = ehdr.e_shnum;
@@ -293,8 +233,8 @@ int main(int argc, char **argv) {
char buf[12];
pread(fd, buf, 12, shstrtab + sh->sh_name);
if(!memcmp(buf, ".init_array", 12)) {
- init_array = v2v(sh->sh_addr);
- init_array_size = sh->sh_size;
+ *init_array = v2v(sh->sh_addr);
+ *init_array_size = sh->sh_size;
}
if(sh->sh_type == SHT_REL) {
notice("SHT_REL");
@@ -310,7 +250,7 @@ int main(int argc, char **argv) {
// notice("Increasing %x which was %x -> %x", offset, *offset, (*offset + (Elf32_Word) reloc_base));
*offset += (Elf32_Word) reloc_base;
} else {
- char *name = strtab + symtab[sym].st_name;
+ char *name = *strtab + (*symtab)[sym].st_name;
void *S = getsym(name);
if(!S) {
notice("Could not find %s", name);
@@ -346,6 +286,72 @@ int main(int argc, char **argv) {
// Stubs away
_assertZero(mprotect(stubs_base, STUBS_SIZE, PROT_READ | PROT_EXEC));
+}
+
+extern void fds_init();
+extern void go(void *NP_Initialize_ptr, void *JNI_OnLoad_ptr);
+
+extern void GSFontInitialize();
+
+int main(int argc, char **argv) {
+ chdir(dirname(argv[0]));
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ char *rpcname = NULL;
+
+ argc--; argv++;
+ while(argc--) {
+ char *p = *argv++;
+ if(!strcmp(p, "-q")) {
+ fclose(stdout);
+ fclose(stderr);
+ } else {
+ _assert(p[0] != '-');
+ rpcname = p;
+ }
+ }
+
+ _assert(rpcname);
+
+ GSFontInitialize(); // magic sauce; if this is not called, CTFontCreate* crashes
+
+ rpc_init(rpcname);
+
+ stubs_base = mmap(NULL, STUBS_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
+ stubs = stubs_base;
+
+ existing_stubs = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+
+ add("/usr/lib/libcrypto.dylib");
+ add("/usr/lib/libssl.dylib");
+ add("/usr/lib/libm.dylib");
+ add("/usr/lib/libSystem.B.dylib");
+ add("./libcutils.dylib");
+ add("./libutils.dylib");
+ add("./libgccstuff.dylib");
+
+ add("./libicudata.42.1.dylib");
+ add("./libicui18n.42.1.dylib");
+ add("./libicuio.42.1.dylib");
+ add("./libicule.42.1.dylib");
+ add("./libiculx.42.1.dylib");
+ add("./libicutu.42.1.dylib");
+ add("./libicuuc.42.1.dylib");
+
+
+ int fd = open("libflashplayer.so", O_RDONLY);
+ _assert(fd > 0);
+
+ fds_init();
+
+ sandbox_me();
+
+ int symtab_size;
+ Elf32_Sym *symtab;
+ void **init_array;
+ Elf32_Word init_array_size;
+ char *strtab;
+ TIME(base_load_elf(fd, &symtab, &symtab_size, &init_array, &init_array_size, &strtab));
// Call the init funcs
_assert(init_array);
View
28 food/neon.S
@@ -0,0 +1,28 @@
+.thumb
+.globl _rgba_bgra_copy
+.thumb_func
+_rgba_bgra_copy:
+ vld4.u8 {d0[0], d1[0], d2[0], d3[0]}, [r1]!
+ vld4.u8 {d0[1], d1[1], d2[1], d3[1]}, [r1]!
+ vld4.u8 {d0[2], d1[2], d2[2], d3[2]}, [r1]!
+ vld4.u8 {d0[3], d1[3], d2[3], d3[3]}, [r1]!
+ vld4.u8 {d0[4], d1[4], d2[4], d3[4]}, [r1]!
+ vld4.u8 {d0[5], d1[5], d2[5], d3[5]}, [r1]!
+ vld4.u8 {d0[6], d1[6], d2[6], d3[6]}, [r1]!
+ vld4.u8 {d0[7], d1[7], d2[7], d3[7]}, [r1]!
+
+ vswp d0, d2
+
+ vst4.u8 {d0[0], d1[0], d2[0], d3[0]}, [r0]!
+ vst4.u8 {d0[1], d1[1], d2[1], d3[1]}, [r0]!
+ vst4.u8 {d0[2], d1[2], d2[2], d3[2]}, [r0]!
+ vst4.u8 {d0[3], d1[3], d2[3], d3[3]}, [r0]!
+ vst4.u8 {d0[4], d1[4], d2[4], d3[4]}, [r0]!
+ vst4.u8 {d0[5], d1[5], d2[5], d3[5]}, [r0]!
+ vst4.u8 {d0[6], d1[6], d2[6], d3[6]}, [r0]!
+ vst4.u8 {d0[7], d1[7], d2[7], d3[7]}, [r0]!
+
+ cmp r1, r2
+ blt _rgba_bgra_copy
+ bx lr
+
View
22 food/np.c
@@ -53,7 +53,7 @@ struct NPFuckedUpVariant {
int32_t whoknows1;
int32_t whoknows2;
int32_t whoknows3;
- } intt;
+ } int_;
};
};
@@ -169,10 +169,20 @@ bool idproxyInvoke(NPObject *obj, NPIdentifier name, const NPVariant *args, uint
struct IDProxyObject *obj_ = (void *) obj;
int prop;
int *args_ = malloc(argCount * sizeof(int));
- _assert(argCount == 0);
- /*int i; for(i = 0; i < argCount; i++) {
- NPFuckedUpVariant *
- }*/
+ int i; for(i = 0; i < argCount; i++) {
+ const struct NPFuckedUpVariant *arg = &(((const struct NPFuckedUpVariant *) args)[i]);
+ int arg_;
+ switch(arg->type) {
+ case NPVariantType_String:
+ assert(!get_string_object(food, (void *) arg->string.value.UTF8Characters, arg->string.value.UTF8Length, &arg_));
+ break;
+ case NPVariantType_Int32:
+ case NPVariantType_Object:
+ default:
+ log("called with unhandled argument type");
+ abort();
+ }
+ }
_assertZero(invoke_object_property(food, obj_->id, (void *) CFDataGetBytePtr(name), CFDataGetLength(name), args_, argCount * sizeof(int), &prop));
free(args_);
if(prop) {
@@ -528,7 +538,7 @@ void go(NP_InitializeFuncPtr NP_Initialize_ptr, void *JNI_OnLoad_ptr_) {
parameters += strlen(k) + 1;
char *v = parameters;
parameters += strlen(v) + 1;
- log("%s -> %s\n", k, v);
+ log("%s -> %s", k, v);
if(strcmp(k, "salign")) {
argn[real_count] = k;
argv[real_count++] = v;
View
2  rpc/food.proto
@@ -2,7 +2,7 @@
> async set_sekrit(buf sekrit);
> async use_surface(int name);
-> async display_sync();
+> async display_sync(int l, int t, int r, int b);
> sync get_parameters(out buf params, out int params_count);
> sync new_connection(stream_t stream, buf url, buf target, out buf url_abs);
> sync get_window_object(out int obj);
Please sign in to comment.
Something went wrong with that request. Please try again.