Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2009 VMware, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  9.  * license, and/or sell copies of the Software, and to permit persons to whom
  10.  * the Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the next
  13.  * paragraph) shall be included in all copies or substantial portions of the
  14.  * Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
  19.  * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  20.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  21.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  22.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. /*
  26.  * This file holds the function implementation for one of the rbug extensions.
  27.  * Prototypes and declerations of functions and structs is in the same folder
  28.  * in the header file matching this file's name.
  29.  *
  30.  * The functions starting rbug_send_* encodes a call to the write format and
  31.  * sends that to the supplied connection, while functions starting with
  32.  * rbug_demarshal_* demarshal data in the wire protocol.
  33.  *
  34.  * Functions ending with _reply are replies to requests.
  35.  */
  36.  
  37. #include "rbug_internal.h"
  38. #include "rbug_texture.h"
  39.  
  40. int rbug_send_texture_list(struct rbug_connection *__con,
  41.                            uint32_t *__serial)
  42. {
  43.         uint32_t __len = 0;
  44.         uint32_t __pos = 0;
  45.         uint8_t *__data = NULL;
  46.         int __ret = 0;
  47.  
  48.         LEN(8); /* header */
  49.  
  50.         /* align */
  51.         PAD(__len, 8);
  52.  
  53.         __data = (uint8_t*)MALLOC(__len);
  54.         if (!__data)
  55.                 return -ENOMEM;
  56.  
  57.         WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_LIST));
  58.         WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
  59.  
  60.         /* final pad */
  61.         PAD(__pos, 8);
  62.  
  63.         if (__pos != __len) {
  64.                 __ret = -EINVAL;
  65.         } else {
  66.                 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_LIST, __len);
  67.                 rbug_connection_write(__con, __data, __len);
  68.                 __ret = rbug_connection_send_finish(__con, __serial);
  69.         }
  70.  
  71.         FREE(__data);
  72.         return __ret;
  73. }
  74.  
  75. int rbug_send_texture_info(struct rbug_connection *__con,
  76.                            rbug_texture_t texture,
  77.                            uint32_t *__serial)
  78. {
  79.         uint32_t __len = 0;
  80.         uint32_t __pos = 0;
  81.         uint8_t *__data = NULL;
  82.         int __ret = 0;
  83.  
  84.         LEN(8); /* header */
  85.         LEN(8); /* texture */
  86.  
  87.         /* align */
  88.         PAD(__len, 8);
  89.  
  90.         __data = (uint8_t*)MALLOC(__len);
  91.         if (!__data)
  92.                 return -ENOMEM;
  93.  
  94.         WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_INFO));
  95.         WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
  96.         WRITE(8, rbug_texture_t, texture); /* texture */
  97.  
  98.         /* final pad */
  99.         PAD(__pos, 8);
  100.  
  101.         if (__pos != __len) {
  102.                 __ret = -EINVAL;
  103.         } else {
  104.                 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_INFO, __len);
  105.                 rbug_connection_write(__con, __data, __len);
  106.                 __ret = rbug_connection_send_finish(__con, __serial);
  107.         }
  108.  
  109.         FREE(__data);
  110.         return __ret;
  111. }
  112.  
  113. int rbug_send_texture_write(struct rbug_connection *__con,
  114.                             rbug_texture_t texture,
  115.                             uint32_t face,
  116.                             uint32_t level,
  117.                             uint32_t zslice,
  118.                             uint32_t x,
  119.                             uint32_t y,
  120.                             uint32_t w,
  121.                             uint32_t h,
  122.                             uint8_t *data,
  123.                             uint32_t data_len,
  124.                             uint32_t stride,
  125.                             uint32_t *__serial)
  126. {
  127.         uint32_t __len = 0;
  128.         uint32_t __pos = 0;
  129.         uint8_t *__data = NULL;
  130.         int __ret = 0;
  131.  
  132.         LEN(8); /* header */
  133.         LEN(8); /* texture */
  134.         LEN(4); /* face */
  135.         LEN(4); /* level */
  136.         LEN(4); /* zslice */
  137.         LEN(4); /* x */
  138.         LEN(4); /* y */
  139.         LEN(4); /* w */
  140.         LEN(4); /* h */
  141.         LEN_ARRAY(1, data); /* data */
  142.         LEN(4); /* stride */
  143.  
  144.         /* align */
  145.         PAD(__len, 8);
  146.  
  147.         __data = (uint8_t*)MALLOC(__len);
  148.         if (!__data)
  149.                 return -ENOMEM;
  150.  
  151.         WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_WRITE));
  152.         WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
  153.         WRITE(8, rbug_texture_t, texture); /* texture */
  154.         WRITE(4, uint32_t, face); /* face */
  155.         WRITE(4, uint32_t, level); /* level */
  156.         WRITE(4, uint32_t, zslice); /* zslice */
  157.         WRITE(4, uint32_t, x); /* x */
  158.         WRITE(4, uint32_t, y); /* y */
  159.         WRITE(4, uint32_t, w); /* w */
  160.         WRITE(4, uint32_t, h); /* h */
  161.         WRITE_ARRAY(1, uint8_t, data); /* data */
  162.         WRITE(4, uint32_t, stride); /* stride */
  163.  
  164.         /* final pad */
  165.         PAD(__pos, 8);
  166.  
  167.         if (__pos != __len) {
  168.                 __ret = -EINVAL;
  169.         } else {
  170.                 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_WRITE, __len);
  171.                 rbug_connection_write(__con, __data, __len);
  172.                 __ret = rbug_connection_send_finish(__con, __serial);
  173.         }
  174.  
  175.         FREE(__data);
  176.         return __ret;
  177. }
  178.  
  179. int rbug_send_texture_read(struct rbug_connection *__con,
  180.                            rbug_texture_t texture,
  181.                            uint32_t face,
  182.                            uint32_t level,
  183.                            uint32_t zslice,
  184.                            uint32_t x,
  185.                            uint32_t y,
  186.                            uint32_t w,
  187.                            uint32_t h,
  188.                            uint32_t *__serial)
  189. {
  190.         uint32_t __len = 0;
  191.         uint32_t __pos = 0;
  192.         uint8_t *__data = NULL;
  193.         int __ret = 0;
  194.  
  195.         LEN(8); /* header */
  196.         LEN(8); /* texture */
  197.         LEN(4); /* face */
  198.         LEN(4); /* level */
  199.         LEN(4); /* zslice */
  200.         LEN(4); /* x */
  201.         LEN(4); /* y */
  202.         LEN(4); /* w */
  203.         LEN(4); /* h */
  204.  
  205.         /* align */
  206.         PAD(__len, 8);
  207.  
  208.         __data = (uint8_t*)MALLOC(__len);
  209.         if (!__data)
  210.                 return -ENOMEM;
  211.  
  212.         WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_READ));
  213.         WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
  214.         WRITE(8, rbug_texture_t, texture); /* texture */
  215.         WRITE(4, uint32_t, face); /* face */
  216.         WRITE(4, uint32_t, level); /* level */
  217.         WRITE(4, uint32_t, zslice); /* zslice */
  218.         WRITE(4, uint32_t, x); /* x */
  219.         WRITE(4, uint32_t, y); /* y */
  220.         WRITE(4, uint32_t, w); /* w */
  221.         WRITE(4, uint32_t, h); /* h */
  222.  
  223.         /* final pad */
  224.         PAD(__pos, 8);
  225.  
  226.         if (__pos != __len) {
  227.                 __ret = -EINVAL;
  228.         } else {
  229.                 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_READ, __len);
  230.                 rbug_connection_write(__con, __data, __len);
  231.                 __ret = rbug_connection_send_finish(__con, __serial);
  232.         }
  233.  
  234.         FREE(__data);
  235.         return __ret;
  236. }
  237.  
  238. int rbug_send_texture_list_reply(struct rbug_connection *__con,
  239.                                  uint32_t serial,
  240.                                  rbug_texture_t *textures,
  241.                                  uint32_t textures_len,
  242.                                  uint32_t *__serial)
  243. {
  244.         uint32_t __len = 0;
  245.         uint32_t __pos = 0;
  246.         uint8_t *__data = NULL;
  247.         int __ret = 0;
  248.  
  249.         LEN(8); /* header */
  250.         LEN(4); /* serial */
  251.         LEN_ARRAY(8, textures); /* textures */
  252.  
  253.         /* align */
  254.         PAD(__len, 8);
  255.  
  256.         __data = (uint8_t*)MALLOC(__len);
  257.         if (!__data)
  258.                 return -ENOMEM;
  259.  
  260.         WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_LIST_REPLY));
  261.         WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
  262.         WRITE(4, uint32_t, serial); /* serial */
  263.         WRITE_ARRAY(8, rbug_texture_t, textures); /* textures */
  264.  
  265.         /* final pad */
  266.         PAD(__pos, 8);
  267.  
  268.         if (__pos != __len) {
  269.                 __ret = -EINVAL;
  270.         } else {
  271.                 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_LIST_REPLY, __len);
  272.                 rbug_connection_write(__con, __data, __len);
  273.                 __ret = rbug_connection_send_finish(__con, __serial);
  274.         }
  275.  
  276.         FREE(__data);
  277.         return __ret;
  278. }
  279.  
  280. int rbug_send_texture_info_reply(struct rbug_connection *__con,
  281.                                  uint32_t serial,
  282.                                  uint32_t target,
  283.                                  uint32_t format,
  284.                                  uint32_t *width,
  285.                                  uint32_t width_len,
  286.                                  uint32_t *height,
  287.                                  uint32_t height_len,
  288.                                  uint32_t *depth,
  289.                                  uint32_t depth_len,
  290.                                  uint32_t blockw,
  291.                                  uint32_t blockh,
  292.                                  uint32_t blocksize,
  293.                                  uint32_t last_level,
  294.                                  uint32_t nr_samples,
  295.                                  uint32_t tex_usage,
  296.                                  uint32_t *__serial)
  297. {
  298.         uint32_t __len = 0;
  299.         uint32_t __pos = 0;
  300.         uint8_t *__data = NULL;
  301.         int __ret = 0;
  302.  
  303.         LEN(8); /* header */
  304.         LEN(4); /* serial */
  305.         LEN(4); /* target */
  306.         LEN(4); /* format */
  307.         LEN_ARRAY(4, width); /* width */
  308.         LEN_ARRAY(4, height); /* height */
  309.         LEN_ARRAY(4, depth); /* depth */
  310.         LEN(4); /* blockw */
  311.         LEN(4); /* blockh */
  312.         LEN(4); /* blocksize */
  313.         LEN(4); /* last_level */
  314.         LEN(4); /* nr_samples */
  315.         LEN(4); /* tex_usage */
  316.  
  317.         /* align */
  318.         PAD(__len, 8);
  319.  
  320.         __data = (uint8_t*)MALLOC(__len);
  321.         if (!__data)
  322.                 return -ENOMEM;
  323.  
  324.         WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_INFO_REPLY));
  325.         WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
  326.         WRITE(4, uint32_t, serial); /* serial */
  327.         WRITE(4, uint32_t, target); /* target */
  328.         WRITE(4, uint32_t, format); /* format */
  329.         WRITE_ARRAY(4, uint32_t, width); /* width */
  330.         WRITE_ARRAY(4, uint32_t, height); /* height */
  331.         WRITE_ARRAY(4, uint32_t, depth); /* depth */
  332.         WRITE(4, uint32_t, blockw); /* blockw */
  333.         WRITE(4, uint32_t, blockh); /* blockh */
  334.         WRITE(4, uint32_t, blocksize); /* blocksize */
  335.         WRITE(4, uint32_t, last_level); /* last_level */
  336.         WRITE(4, uint32_t, nr_samples); /* nr_samples */
  337.         WRITE(4, uint32_t, tex_usage); /* tex_usage */
  338.  
  339.         /* final pad */
  340.         PAD(__pos, 8);
  341.  
  342.         if (__pos != __len) {
  343.                 __ret = -EINVAL;
  344.         } else {
  345.                 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_INFO_REPLY, __len);
  346.                 rbug_connection_write(__con, __data, __len);
  347.                 __ret = rbug_connection_send_finish(__con, __serial);
  348.         }
  349.  
  350.         FREE(__data);
  351.         return __ret;
  352. }
  353.  
  354. int rbug_send_texture_read_reply(struct rbug_connection *__con,
  355.                                  uint32_t serial,
  356.                                  uint32_t format,
  357.                                  uint32_t blockw,
  358.                                  uint32_t blockh,
  359.                                  uint32_t blocksize,
  360.                                  uint8_t *data,
  361.                                  uint32_t data_len,
  362.                                  uint32_t stride,
  363.                                  uint32_t *__serial)
  364. {
  365.         uint32_t __len = 0;
  366.         uint32_t __pos = 0;
  367.         uint8_t *__data = NULL;
  368.         int __ret = 0;
  369.  
  370.         LEN(8); /* header */
  371.         LEN(4); /* serial */
  372.         LEN(4); /* format */
  373.         LEN(4); /* blockw */
  374.         LEN(4); /* blockh */
  375.         LEN(4); /* blocksize */
  376.         LEN_ARRAY(1, data); /* data */
  377.         LEN(4); /* stride */
  378.  
  379.         /* align */
  380.         PAD(__len, 8);
  381.  
  382.         __data = (uint8_t*)MALLOC(__len);
  383.         if (!__data)
  384.                 return -ENOMEM;
  385.  
  386.         WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_READ_REPLY));
  387.         WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
  388.         WRITE(4, uint32_t, serial); /* serial */
  389.         WRITE(4, uint32_t, format); /* format */
  390.         WRITE(4, uint32_t, blockw); /* blockw */
  391.         WRITE(4, uint32_t, blockh); /* blockh */
  392.         WRITE(4, uint32_t, blocksize); /* blocksize */
  393.         WRITE_ARRAY(1, uint8_t, data); /* data */
  394.         WRITE(4, uint32_t, stride); /* stride */
  395.  
  396.         /* final pad */
  397.         PAD(__pos, 8);
  398.  
  399.         if (__pos != __len) {
  400.                 __ret = -EINVAL;
  401.         } else {
  402.                 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_READ_REPLY, __len);
  403.                 rbug_connection_write(__con, __data, __len);
  404.                 __ret = rbug_connection_send_finish(__con, __serial);
  405.         }
  406.  
  407.         FREE(__data);
  408.         return __ret;
  409. }
  410.  
  411. struct rbug_proto_texture_list * rbug_demarshal_texture_list(struct rbug_proto_header *header)
  412. {
  413.         struct rbug_proto_texture_list *ret;
  414.  
  415.         if (!header)
  416.                 return NULL;
  417.         if (header->opcode != (int32_t)RBUG_OP_TEXTURE_LIST)
  418.                 return NULL;
  419.  
  420.         ret = MALLOC(sizeof(*ret));
  421.         if (!ret)
  422.                 return NULL;
  423.  
  424.         ret->header.__message = header;
  425.         ret->header.opcode = header->opcode;
  426.  
  427.         return ret;
  428. }
  429.  
  430. struct rbug_proto_texture_info * rbug_demarshal_texture_info(struct rbug_proto_header *header)
  431. {
  432.         uint32_t len = 0;
  433.         uint32_t pos = 0;
  434.         uint8_t *data =  NULL;
  435.         struct rbug_proto_texture_info *ret;
  436.  
  437.         if (!header)
  438.                 return NULL;
  439.         if (header->opcode != (int32_t)RBUG_OP_TEXTURE_INFO)
  440.                 return NULL;
  441.  
  442.         pos = 0;
  443.         len = header->length * 4;
  444.         data = (uint8_t*)&header[1];
  445.         ret = MALLOC(sizeof(*ret));
  446.         if (!ret)
  447.                 return NULL;
  448.  
  449.         ret->header.__message = header;
  450.         ret->header.opcode = header->opcode;
  451.  
  452.         READ(8, rbug_texture_t, texture); /* texture */
  453.  
  454.         return ret;
  455. }
  456.  
  457. struct rbug_proto_texture_write * rbug_demarshal_texture_write(struct rbug_proto_header *header)
  458. {
  459.         uint32_t len = 0;
  460.         uint32_t pos = 0;
  461.         uint8_t *data =  NULL;
  462.         struct rbug_proto_texture_write *ret;
  463.  
  464.         if (!header)
  465.                 return NULL;
  466.         if (header->opcode != (int32_t)RBUG_OP_TEXTURE_WRITE)
  467.                 return NULL;
  468.  
  469.         pos = 0;
  470.         len = header->length * 4;
  471.         data = (uint8_t*)&header[1];
  472.         ret = MALLOC(sizeof(*ret));
  473.         if (!ret)
  474.                 return NULL;
  475.  
  476.         ret->header.__message = header;
  477.         ret->header.opcode = header->opcode;
  478.  
  479.         READ(8, rbug_texture_t, texture); /* texture */
  480.         READ(4, uint32_t, face); /* face */
  481.         READ(4, uint32_t, level); /* level */
  482.         READ(4, uint32_t, zslice); /* zslice */
  483.         READ(4, uint32_t, x); /* x */
  484.         READ(4, uint32_t, y); /* y */
  485.         READ(4, uint32_t, w); /* w */
  486.         READ(4, uint32_t, h); /* h */
  487.         READ_ARRAY(1, uint8_t, data); /* data */
  488.         READ(4, uint32_t, stride); /* stride */
  489.  
  490.         return ret;
  491. }
  492.  
  493. struct rbug_proto_texture_read * rbug_demarshal_texture_read(struct rbug_proto_header *header)
  494. {
  495.         uint32_t len = 0;
  496.         uint32_t pos = 0;
  497.         uint8_t *data =  NULL;
  498.         struct rbug_proto_texture_read *ret;
  499.  
  500.         if (!header)
  501.                 return NULL;
  502.         if (header->opcode != (int32_t)RBUG_OP_TEXTURE_READ)
  503.                 return NULL;
  504.  
  505.         pos = 0;
  506.         len = header->length * 4;
  507.         data = (uint8_t*)&header[1];
  508.         ret = MALLOC(sizeof(*ret));
  509.         if (!ret)
  510.                 return NULL;
  511.  
  512.         ret->header.__message = header;
  513.         ret->header.opcode = header->opcode;
  514.  
  515.         READ(8, rbug_texture_t, texture); /* texture */
  516.         READ(4, uint32_t, face); /* face */
  517.         READ(4, uint32_t, level); /* level */
  518.         READ(4, uint32_t, zslice); /* zslice */
  519.         READ(4, uint32_t, x); /* x */
  520.         READ(4, uint32_t, y); /* y */
  521.         READ(4, uint32_t, w); /* w */
  522.         READ(4, uint32_t, h); /* h */
  523.  
  524.         return ret;
  525. }
  526.  
  527. struct rbug_proto_texture_list_reply * rbug_demarshal_texture_list_reply(struct rbug_proto_header *header)
  528. {
  529.         uint32_t len = 0;
  530.         uint32_t pos = 0;
  531.         uint8_t *data =  NULL;
  532.         struct rbug_proto_texture_list_reply *ret;
  533.  
  534.         if (!header)
  535.                 return NULL;
  536.         if (header->opcode != (int32_t)RBUG_OP_TEXTURE_LIST_REPLY)
  537.                 return NULL;
  538.  
  539.         pos = 0;
  540.         len = header->length * 4;
  541.         data = (uint8_t*)&header[1];
  542.         ret = MALLOC(sizeof(*ret));
  543.         if (!ret)
  544.                 return NULL;
  545.  
  546.         ret->header.__message = header;
  547.         ret->header.opcode = header->opcode;
  548.  
  549.         READ(4, uint32_t, serial); /* serial */
  550.         READ_ARRAY(8, rbug_texture_t, textures); /* textures */
  551.  
  552.         return ret;
  553. }
  554.  
  555. struct rbug_proto_texture_info_reply * rbug_demarshal_texture_info_reply(struct rbug_proto_header *header)
  556. {
  557.         uint32_t len = 0;
  558.         uint32_t pos = 0;
  559.         uint8_t *data =  NULL;
  560.         struct rbug_proto_texture_info_reply *ret;
  561.  
  562.         if (!header)
  563.                 return NULL;
  564.         if (header->opcode != (int32_t)RBUG_OP_TEXTURE_INFO_REPLY)
  565.                 return NULL;
  566.  
  567.         pos = 0;
  568.         len = header->length * 4;
  569.         data = (uint8_t*)&header[1];
  570.         ret = MALLOC(sizeof(*ret));
  571.         if (!ret)
  572.                 return NULL;
  573.  
  574.         ret->header.__message = header;
  575.         ret->header.opcode = header->opcode;
  576.  
  577.         READ(4, uint32_t, serial); /* serial */
  578.         READ(4, uint32_t, target); /* target */
  579.         READ(4, uint32_t, format); /* format */
  580.         READ_ARRAY(4, uint32_t, width); /* width */
  581.         READ_ARRAY(4, uint32_t, height); /* height */
  582.         READ_ARRAY(4, uint32_t, depth); /* depth */
  583.         READ(4, uint32_t, blockw); /* blockw */
  584.         READ(4, uint32_t, blockh); /* blockh */
  585.         READ(4, uint32_t, blocksize); /* blocksize */
  586.         READ(4, uint32_t, last_level); /* last_level */
  587.         READ(4, uint32_t, nr_samples); /* nr_samples */
  588.         READ(4, uint32_t, tex_usage); /* tex_usage */
  589.  
  590.         return ret;
  591. }
  592.  
  593. struct rbug_proto_texture_read_reply * rbug_demarshal_texture_read_reply(struct rbug_proto_header *header)
  594. {
  595.         uint32_t len = 0;
  596.         uint32_t pos = 0;
  597.         uint8_t *data =  NULL;
  598.         struct rbug_proto_texture_read_reply *ret;
  599.  
  600.         if (!header)
  601.                 return NULL;
  602.         if (header->opcode != (int32_t)RBUG_OP_TEXTURE_READ_REPLY)
  603.                 return NULL;
  604.  
  605.         pos = 0;
  606.         len = header->length * 4;
  607.         data = (uint8_t*)&header[1];
  608.         ret = MALLOC(sizeof(*ret));
  609.         if (!ret)
  610.                 return NULL;
  611.  
  612.         ret->header.__message = header;
  613.         ret->header.opcode = header->opcode;
  614.  
  615.         READ(4, uint32_t, serial); /* serial */
  616.         READ(4, uint32_t, format); /* format */
  617.         READ(4, uint32_t, blockw); /* blockw */
  618.         READ(4, uint32_t, blockh); /* blockh */
  619.         READ(4, uint32_t, blocksize); /* blocksize */
  620.         READ_ARRAY(1, uint8_t, data); /* data */
  621.         READ(4, uint32_t, stride); /* stride */
  622.  
  623.         return ret;
  624. }
  625.