0

Hi everyone I spend the past weekend trying to put a png image on the screen but without success. I look left and right to why but no matter what I try I can't seem to find why could someone point me to the right direction?

I was using this as a template. Then i looked at all of those :

libX11: XPutImage first call

Having issues with XPutImage

displaying png file using XPutImage does not work

but steal nothing

XPutImage(display,
              *window,
              ((mc_drawable *)this)->_gc,
              this->image,
              0, 0,
              0, 0,
              this->_y, this->_x);

this is how I use XPutImage

#include <png.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include "modular/raise.h"
#include "internal/drawable/imagepr.h"
#include "internal/server_connection.h"

static void chechFile(
    FILE *file)
{
    unsigned char nbr[8] = "";

    fread(nbr, 1, 8, file);
    if (png_sig_cmp(nbr, 0, 8) != 0) {
        raise("not a Png file");
    }
}

static char parsePng(
    FILE *file,
    mc_imagePr *image)
{
    char *data = NULL;
    png_struct *pngPtr = png_create_read_struct(
        PNG_LIBPNG_VER_STRING,
        NULL, NULL, NULL);
    png_info *pngInfo = NULL;
    int readFlag = PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND;
    int colorType = 0;
    int interlaceMethod = 0;
    int rowBytes = 0;
    png_uint_32 index = 0;
    png_bytepp rowPointers = NULL;
    png_uint_32 width = 0;
    png_uint_32 height = 0;
    int bitDepth = 0;
    Display *dys = getDisplay();

    if (!pngPtr) {
        return (0);
    } else if (!(pngInfo = png_create_info_struct(pngPtr))) {
        png_destroy_read_struct(&pngPtr, NULL, NULL);
        return (0);
    }
    if (setjmp(png_jmpbuf(pngPtr))) {
        png_destroy_read_struct(&pngPtr, &pngInfo, NULL);
        return (0);
    }
    png_init_io(pngPtr, file);
    png_set_sig_bytes(pngPtr, 8);
    png_read_png(pngPtr, pngInfo, readFlag, NULL);
    png_get_IHDR(pngPtr,
                 pngInfo,
                 &width, &height,
                 &bitDepth,
                 &colorType,
                 &interlaceMethod,
                 NULL,
                 NULL);

    rowBytes = png_get_rowbytes(pngPtr, pngInfo);
    data = malloc(rowBytes * height);
    if (!data) {
        png_destroy_read_struct(&pngPtr, &pngInfo, NULL);
        return (0);
    }
    rowPointers = png_get_rows(pngPtr, pngInfo);
    while (index < height) {
        memcpy(data + (index * rowBytes),
               rowPointers[index],
               rowBytes);
        ++index;
    }
    printf("PNG %d * %d\n rowbytes %d\n depth %d\ncolor type %d\n",
           width,
           height,
           rowBytes,
           bitDepth,
           colorType);
    image->image = XCreateImage(
        dys,
        CopyFromParent,
        DefaultDepth(
            dys,
            DefaultScreen(dys)),
        ZPixmap,
        0,
        data,
        width,
        height,
        32,
        rowBytes);
    png_destroy_info_struct(pngPtr, &pngInfo);
    png_destroy_read_struct(&pngPtr, &pngInfo, NULL);
    return (1);
}

char readPng(
    const char *path,
    mc_imagePr *image)
{
    FILE *fd = fopen(path, "r");
    char res = 0;

    if (!fd) {
        raise("file not found\n");
    }
    chechFile(fd);
    res = parsePng(
        fd,
        image);
    fclose(fd);
    return (res);
}

This is the file I use to create my XImage

Edit:

after reading the reply of N.M. i try to draw a 50 by 50 white image once again whtout succes. Whitch mean i realy did not anderstood how XPutImage work. here is my test for that:

 #include <memory.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <X11/Xlib.h>
 #include <stdio.h>
 #include <unistd.h>

 int main(void)
 {
     Window window;
     Display *display = XOpenDisplay();
     XSetWindowAttributes test = {};
     XEvent e;
     GC gc;
     int whiteColor;
     Atom delWin = XInternAtom(display, "WM_DELETE_WINDOW", True);
     XImage *image = NULL;
     char *data = malloc(50 * 50 * 4);

     memset(data, 250, 50 * 50 * 4);
     if (!display) {
         return (84);
     }
     window = XCreateWindow(
         display,
         XDefaultRootWindow(display),
         0, 0,
         500, 500,
         100,
         CopyFromParent,
         CopyFromParent,
         CopyFromParent,
         0,
         &test);
     XSelectInput(display, window, StructureNotifyMask);
     XMapWindow(display, window);
     gc = XCreateGC(display, window, 0, 0);
     whiteColor = WhitePixel(display, DefaultScreen(display));
     XSetForeground(display, gc, whiteColor);
     XSetWMProtocols(display, window, &delWin, 1);
     while (1) {
         XNextEvent(display, &e);
         if (e.type == MapNotify)
             break;
     }
     XFlush(display);
         image = XCreateImage(
         display,
         CopyFromParent,
         DefaultDepth(
             display,
             DefaultScreen(display)),
         ZPixmap,
         0,
         data,
         50,
         50,
         32,
         50 * 4);
     while (1) {
         XNextEvent(display, &e);
         if (e.type == DestroyNotify ||
             (e.type == ClientMessage &&
              e.xclient.data.l[0] == (long)delWin))
             break;
         XPutImage(
             display,
             window,
             gc,
             image,
             0, 0,
             50, 50,
             0, 0);
     }
     XCloseDisplay(display);
     return (0);
julia
  • 139
  • 3
  • 11
  • does the png read succeed? have you tried exporting the bitmap to file e.g. using PGM-format? – Andreas Apr 01 '19 at 16:53
  • Posted code isn't nearly sufficient to even start thinking about what could possibly be wrong. I suggest you try to identify the specific issue first. Can you read the png file correctly? (Parse it, print out the top left 50x50 corner as a byte array, visually compare). Can you use XPutImage? (create a 50x50 white image, 50x50 black image, use tem to test). – n. m. could be an AI Apr 02 '19 at 06:12
  • @n.m. I was not able to display a 50*50 white square. I edited the code up top to add a minimalist example of what I'm doing – julia Apr 02 '19 at 16:20
  • Please make sure code that you post compiles on its own. What is my_window.h, what is connect_to_server, etc. – n. m. could be an AI Apr 02 '19 at 17:53
  • The last two parameters of XPutImage are width and height. If you pass two zeroes you won't see anything... – n. m. could be an AI Apr 02 '19 at 18:01
  • should compile fine now – julia Apr 02 '19 at 18:04
  • Thank you it was in dead the problem and now I feel kinda dumb. – julia Apr 02 '19 at 19:13

1 Answers1

0

I feel kinda dumb but I just swap 2 lines and wasn't able to see it. Thanks to n.m. how help me figured it out

int main(void)
{
     Window window;
     Display *display = XOpenDisplay();
     XSetWindowAttributes test = {};
     XEvent e;
     GC gc;
     int whiteColor;
     Atom delWin = XInternAtom(display, "WM_DELETE_WINDOW", True);
     XImage *image = NULL;
     char *data = malloc(50 * 50 * 4);

     memset(data, 250, 50 * 50 * 4);
     if (!display) {
         return (84);
     }
     window = XCreateWindow(
         display,
         XDefaultRootWindow(display),
         0, 0,
         500, 500,
         100,
         CopyFromParent,
         CopyFromParent,
         CopyFromParent,
         0,
         &test);
     XSelectInput(display, window, StructureNotifyMask);
     XMapWindow(display, window);
     gc = XCreateGC(display, window, 0, 0);
     whiteColor = WhitePixel(display, DefaultScreen(display));
     XSetForeground(display, gc, whiteColor);
     XSetWMProtocols(display, window, &delWin, 1);
     while (1) {
         XNextEvent(display, &e);
         if (e.type == MapNotify)
             break;
     }
     XFlush(display);
         image = XCreateImage(
         display,
         CopyFromParent,
         DefaultDepth(
             display,
             DefaultScreen(display)),
         ZPixmap,
         0,
         data,
         50,
         50,
         32,
         50 * 4);
     while (1) {
         XNextEvent(display, &e);
         if (e.type == DestroyNotify ||
             (e.type == ClientMessage &&
              e.xclient.data.l[0] == (long)delWin))
             break;
         XPutImage(
             display,
             window,
             gc,
             image,
             0, 0,  // from which offset to start drawing
             0, 0,  // position on the screen
             50, 50); // width and height of what you want to draw
     }
     XCloseDisplay(display);
     return (0);
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
julia
  • 139
  • 3
  • 11