Start the gui program as non-root in systemd

Run ps -ef to find that the process number of upstart is 1566. When the parent process id of my gui program is 1566, it can be displayed normally. Now there are several problems that cause my gui program to not run normally.

  1. I have a systemd program, its name is terui. I want to start my gui program in terui. This is my startup code: system("su sunxy -c 'DISPLAY=:0 XAUTHORITY=/home/sunxy/.Xauthority /etc/opt/kpki/mw/KCliBaseService/start_tray.sh'");

  2. I found that after starting in this way, the parent process id of the gui program was 1, not 1566, which caused my gui program to fail to display normally. When I enter su sunxy -c’DISPLAY=:0 XAUTHORITY=/home/sunxy/.Xauthority /etc/opt/kpki/mw/KCliBaseService/start_tray.sh’ as a root user in bash, my gui program can be displayed normally, and its parent process id is 1566.

  3. This is my terui.service:

(Unit)
Description=terui Daemon
Requires=network-online.target
After=network-online.target

(Service)
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/sunxy/.Xauthority"
ExecStart=/home/testui/build/terui
User=root
Type=simple
Restart=always
RestartSec=3s
(Install)
WantedBy=graphical.target

So, my question is, what should I do to display the gui program normally

menu – Is there a c program with code encryption and decryption

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.

How to Write a Contact List Program In C++ That Pulls Out the Corresponding Phone Number for an Entered Contact Name

I have written a program in C++ that takes in string values for contact names and contact phone numbers into vectors. What I need to do is have the program output the corresponding phone number for the contact name entered.

(Note: The ‘3’ is supposed to tell the program how many values are to be stored in each vector. In this case, it is 3 contact names and 3 phone numbers. Also, the last ‘Frank’ indicates that the corresponding phone number printed should be for the contact name ‘Frank’.)

Ex. Input: 3 Joe 123-5432 Linda 983-4123 Frank 867-5309 Frank

Ex. Output: 867-5309

When I run the program instead of getting the desired phone number it outputs nothing.

Here is the program that I have written so far:

#include <iostream>
#include <vector>
using namespace std;

string GetPhoneNumber(vector<string> nameVec, vector<string> phoneNumberVec, string contactName)  {
   
   string theName;
   string thePhoneNum;
   string theContName;
   string correctPhonNum;
   int N;
   int nElements;
   
   cin >> N;
   
   cin >> theName;
   cin >> thePhoneNum;
   cin >> theName;
   cin >> thePhoneNum;
   cin >> theName;
   cin >> thePhoneNum;
   
   nameVec.push_back(theName);
   phoneNumberVec.push_back(thePhoneNum);
   
   cin >> contactName;
   
   nElements = phoneNumberVec.size(); 
   
   for (int i = 0; i < nElements; i++)  {
      if (i == N-1)  {
         return phoneNumberVec.at(i); 
      }
   }
   return "";
}

int main() {
   
   vector<string> nameVec;
   vector<string> phoneNumberVec;
   string contactName;
   string correctPhonNum;
   
   GetPhoneNumber(nameVec, phoneNumberVec, contactName);
   
   cout << correctPhonNum << endl;

   return 0;
}

coding style – How should you program your C++ application to handle signals STOP CONT HUP INT TERM KILL USR1 USR2, etc?

Background

I have been expanding a download library, in which I want to store its progress by writing the accumulated bytes to a database before its overarching application gets killed, either through error or shutdown or whatever. I had inquired about whether its destructor would be run when I close an application. I did not get a clear answer however, and said it was heavily dependent upon the signal being sent, and was linked to this library here: https://www.cplusplus.com/reference/cstdlib/atexit/

Questions

I went to my task manager and quickly wrote down all the signals I could send an application, them being:

  • STOP – Suspend
  • CONT – Continue
  • HUP – Hangup
  • INT – Interrupt
  • TERM – Terminate
  • KILL – Kill
  • USR1 – User 1
  • USR2 – User 2
  1. Are these signals synonymous with the signals found here https://unix.stackexchange.com/a/317496/79280
    and from typing man 7 signal? If so, why are these ones most likely picked specifically to be included in my task manager, omitting the others?
  2. Broadly speaking, how do each one of these signals interact with your application?
  3. Of these signals, which will call a destructor?
  4. When programming for them, do the libraries such as https://www.cplusplus.com/reference/cstdlib/atexit/ exist only in std::lib, or does Qt, Boost, etc have their own implementations and means of dealing with such?
  5. Are there any signals here which you can not program for? Why or Why not?
  6. Is there any literature, or standards, or coding styles which account for how one should treat these signals inside your program?

Thanks.

So I have this question in one of my interview practice problem and I’m not that familiar with Java, So how I do make a program like this

A Java program to that performs the following tasks:
(10 Points) Accepts integer input (one integer at a time) from the user.
(50 Points) Inserts the given integer into an integer array of size 10 in ascending order. If the array is full the latest integer input (x) will replace the largest integer in the array that is smaller than x. In order to satisfy this requirement your program must –
Replace any existing value at that index with x
Find the appropriate location (index) to insert x.
(20 Points) Print the current contents of the integer array
(20 Points) Ask if the user wants to continue. If yes go to step 1 else exit the program

Earn Extra cash $100 per unique referral Join our Affiliate Program for Big Payouts!

We are now offering up to $100 for every unique referral to WireNine.com

WireNine’s Web Hosting Affiliate program is simple and easy to use. We provide you with all the necessary tools to make this is a success! Having a Web hosting account with us is not required.

For example, you will earn $100 x 25 = $2500 if you send us 25 new signups. (Contact our affiliate team if you can send more than 25 sign-ups in a month!)

Reasons To Join

  • It’s FREE to Join!
  • Get a $5 bonus just for signing up! (Limited Time Only!)
  • You don’t have to be a WireNine client to be a web hosting affiliate.
  • The more you sell the more you EARN!
  • Real-time reporting
  • Use our banners and links or create your own.

WireNine’s affiliate program is easy to use with extremely accurate tracking methods. Sign up now and start earning today!

Go to https://www.wirenine.com/affiliates for more details and to sign up!
SEMrush

 

c – a simple interrupt polling program due to AXI DMA IP

The program transfers a data array from a Zynq-7000 PS DDR to a BRAM IP (block RAM) memory in a PL part of a FPGA due to a PL AXI DMA IP. Inferring a xilinx axi dma driver (not scatter-gather mode), an interrupt controller and the vendor’s printf function the data array is carried from the DDR to the BRAM.

main.c

#include "xstatus.h"

#include "platform_.h"
#include "axi_dma_intr_poll.h"

#define TX_BUFFER               (uint32_t *) 0x01100000
#define RX_BUFFER               (uint32_t *) XPAR_BRAM_0_BASEADDR

#define RESET_TIMEOUT_CNTR_VAL  0x1000
#define MAX_TX_VALUE            0x100
#define PAYLOAD_SIZE            MAX_TX_VALUE

volatile _Bool tx_done_flag, rx_done_flag, tx_error, rx_error;

axi_dma_init_str init;
axi_dma_poll_str poll;
axi_dma_handler_str handler;

static void tx_intr_handler(void *callback);
static void rx_intr_handler(void *callback);

static inline void printf_array(uint32_t *p_array, size_t size);

int main(void) {

    uint8_t mul_coefficient = 0;
    const uint8_t c_ascii_num_offset = 0x30;
    uint32_t i = 0;

    memset((uint8_t *) XPAR_BRAM_0_BASEADDR,0,0x100);

    init.dma_id = XPAR_AXIDMA_0_DEVICE_ID;
    init.rx_intr_handler = rx_intr_handler;
    init.tx_intr_handler = tx_intr_handler;
    init.rx_intr_id = XPAR_FABRIC_AXIDMA_0_S2MM_INTROUT_VEC_ID;
    init.tx_intr_id = XPAR_FABRIC_AXIDMA_0_MM2S_INTROUT_VEC_ID;

    poll.p_tx_buf = TX_BUFFER;
    poll.p_rx_buf = RX_BUFFER;
    poll.size = PAYLOAD_SIZE;

    axi_dma_init(&init, &handler);

    while(1) {
        xil_printf("AXI DMA %d: ready. Insert multiplier coefficient (1 - 9): ", init.dma_id);

        mul_coefficient = inbyte();
        mul_coefficient -= c_ascii_num_offset;
        xil_printf("%dnr", mul_coefficient);

        for(i = 0; i < MAX_TX_VALUE; i++) {
            poll.p_tx_buf(i) = (i * mul_coefficient) % MAX_TX_VALUE;
        }

        tx_done_flag = FALSE;
        rx_done_flag = FALSE;

        axi_dma_poll(&poll, &handler.axi_dma, init.dma_id);

        xil_printf("AXI DMA %d: waiting completion of the poll...", init.dma_id);

        while((FALSE == tx_done_flag) || (FALSE == rx_done_flag)) {
            asm("NOP");
        }

        if ((TRUE == tx_error) || (TRUE == rx_error)) {
            xil_printf("AXI DMA %d ERROR: the polling ERROR", init.dma_id);
        }
        else {
            xil_printf("nnrAXI DMA %d: the tx buffer:nr", init.dma_id);
            printf_array(TX_BUFFER ,PAYLOAD_SIZE);

            xil_printf("nnrAXI DMA %d: the rx buffer:nr", init.dma_id);
            printf_array(RX_BUFFER, PAYLOAD_SIZE);
        }

        xil_printf("nnr");
    }

    return XST_SUCCESS;
}

static void tx_intr_handler(void *callback) {

    uint32_t status = 0;
    int reset_cntr = RESET_TIMEOUT_CNTR_VAL;
    XAxiDma *axi_dma = (XAxiDma *) callback;

    status = XAxiDma_IntrGetIrq(axi_dma, XAXIDMA_DMA_TO_DEVICE);

    XAxiDma_IntrAckIrq(axi_dma, status, XAXIDMA_DMA_TO_DEVICE);

    tx_done_flag = TRUE;

    if (FALSE != (status & XAXIDMA_IRQ_ALL_MASK) &&
       (TRUE == (status & XAXIDMA_IRQ_ERROR_MASK))) {
        tx_error = TRUE;
        XAxiDma_Reset(axi_dma);

        while (reset_cntr--) {
            if (XAxiDma_ResetIsDone(axi_dma)) {
                break;
            }

        }
    }
}


static void rx_intr_handler(void *callback)
{
    uint32_t status = 0;
    int reset_cntr = RESET_TIMEOUT_CNTR_VAL;
    XAxiDma *axi_dma = (XAxiDma *) callback;

    status = XAxiDma_IntrGetIrq(axi_dma, XAXIDMA_DEVICE_TO_DMA);

    XAxiDma_IntrAckIrq(axi_dma, status, XAXIDMA_DEVICE_TO_DMA);

    rx_done_flag = TRUE;

    if ((FALSE != (status & XAXIDMA_IRQ_ALL_MASK)) &&
       (TRUE == (status & XAXIDMA_IRQ_ERROR_MASK))) {
        rx_error = TRUE;
        XAxiDma_Reset(axi_dma);

        while (reset_cntr--) {
            if (XAxiDma_ResetIsDone(axi_dma)) {
                break;
            }
        }
    }
}

static inline void printf_array(uint32_t *p_array, size_t size) {
    const uint8_t c_values_per_line = 10;
    uint32_t i = 0;

    for(i = 0; i < size; i++) {
        xil_printf("%d ", *(TX_BUFFER + i));

        if (FALSE == (i % c_values_per_line) && (0 != i)) {
            xil_printf("nr");
        }
    }
}

axi_dma_intr_poll.c

#include "xil_exception.h"

#include "axi_dma_intr_poll.h"

static int enable_intr_(axi_dma_handler_str *p_handler, axi_dma_init_str *p_init);

int axi_dma_init(axi_dma_init_str *p_init, axi_dma_handler_str *p_handler) {

    if ((NULL == p_init) || (NULL == p_handler)) {
        xil_printf("AXI DMA %d ERROR: the entire axi_dma_init function ERRORrn", p_init->dma_id);
        return XST_FAILURE;
    }

    memset(p_handler, 0, sizeof(axi_dma_handler_str));

    p_handler->p_config = XAxiDma_LookupConfig(p_init->dma_id);
    if (NULL == p_handler->p_config) {
        xil_printf("AXI DMA %d ERROR: the dma lookup config FAILEDrn", p_init->dma_id);
        return XST_FAILURE;
    }

    if (XST_SUCCESS != XAxiDma_CfgInitialize(&(p_handler->axi_dma), p_handler->p_config)) {
        xil_printf("AXI DMA %d ERROR: the dma initialization FAILEDrn", p_init->dma_id);
        return XST_FAILURE;
    }

    if(TRUE == XAxiDma_HasSg(&(p_handler->axi_dma))){
        xil_printf("AXI DMA %d ERROR: the device configured as SG modern", p_init->dma_id);
        return XST_FAILURE;
    }

    if (XST_SUCCESS != enable_intr_(p_handler, p_init)) {
        xil_printf("AXI DMA %d ERROR: the interrupt setup FAILEDrn");
        return XST_FAILURE;
    }

    return XST_SUCCESS;
}

int axi_dma_poll(axi_dma_poll_str *p_poll, XAxiDma *p_axi_dma, uint32_t dma_id) {

    if ((NULL == p_poll) || (NULL == p_axi_dma)) {
        xil_printf("AXI DMA %d ERROR: the entire axi_dma_poll function ERRORrn", dma_id);
        return XST_FAILURE;
    }

    Xil_DCacheFlushRange((UINTPTR) (p_poll->p_tx_buf), p_poll->size);

    if (XST_SUCCESS != XAxiDma_SimpleTransfer(p_axi_dma,(UINTPTR) (p_poll->p_tx_buf),
                                              p_poll->size, XAXIDMA_DMA_TO_DEVICE)) {
        xil_printf("AXI DMA %d ERROR: the tx buffer setting FAILEDrn", dma_id);
        return XST_FAILURE;
    }

    if (XST_SUCCESS != XAxiDma_SimpleTransfer(p_axi_dma,(UINTPTR) (p_poll->p_rx_buf),
                                              p_poll->size, XAXIDMA_DEVICE_TO_DMA)) {
        xil_printf("AXI DMA %d ERROR: the rx buffer setting FAILEDrn", dma_id);
        return XST_FAILURE;
    }

    return XST_SUCCESS;
}

int axi_dma_release(XScuGic *p_scu_gic, uint32_t tx_intr_id, uint32_t rx_intr_id) {

    if ((NULL == p_scu_gic) || (0 == tx_intr_id) || (0 == rx_intr_id)) {
        xil_printf("AXI DMA %d ERROR: the entire axi_dma_release function ERRORrn", p_scu_gic->Config->DeviceId);
        return XST_FAILURE;
    }

    XScuGic_Disconnect(p_scu_gic, tx_intr_id);
    XScuGic_Disconnect(p_scu_gic, rx_intr_id);

    return XST_SUCCESS;
}

static int enable_intr_(axi_dma_handler_str *p_handler, axi_dma_init_str *p_init) {

    const uint8_t c_priority = 0xA0, c_trigger_type = 0x3;

    p_handler->p_intc_config = XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);
    if (NULL == p_handler->p_intc_config) {
        xil_printf("AXI DMA %d ERROR: the scu gic lookup config FAILEDrn", p_init->dma_id);
        return XST_FAILURE;
    }

    if (XST_SUCCESS != XScuGic_CfgInitialize(&(p_handler->scu_gic), p_handler->p_intc_config,
                                               p_handler->p_intc_config->CpuBaseAddress)) {
        xil_printf("AXI DMA %d ERROR: the scu gic initialization FAILEDrn", p_init->dma_id);
        return XST_FAILURE;
    }

    XScuGic_SetPriorityTriggerType(&(p_handler->scu_gic), p_init->tx_intr_id, c_priority, c_trigger_type);
    XScuGic_SetPriorityTriggerType(&(p_handler->scu_gic), p_init->rx_intr_id, c_priority, c_trigger_type);

    if (XST_SUCCESS != XScuGic_Connect(&(p_handler->scu_gic), p_init->tx_intr_id,
                                      (Xil_InterruptHandler)p_init->tx_intr_handler,
                                      &(p_handler->axi_dma))) {
        xil_printf("AXI DMA %d ERROR: the scu gic tx connection FAILEDrn", p_init->dma_id);
        return XST_FAILURE;
    }

    if (XST_SUCCESS != XScuGic_Connect(&(p_handler->scu_gic), p_init->rx_intr_id,
                                      (Xil_InterruptHandler)p_init->rx_intr_handler,
                                      &(p_handler->axi_dma))) {
        xil_printf("AXI DMA %d ERROR: the scu gic rx connection FAILEDrn", p_init->dma_id);
        return XST_FAILURE;
    }

    XScuGic_Enable(&(p_handler->scu_gic), p_init->tx_intr_id);
    XScuGic_Enable(&(p_handler->scu_gic), p_init->rx_intr_id);

    Xil_ExceptionInit();
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler,
                                (void *)&(p_handler->scu_gic));

    Xil_ExceptionEnable();

    XAxiDma_IntrDisable(&(p_handler->axi_dma), XAXIDMA_IRQ_ALL_MASK,
                       XAXIDMA_DMA_TO_DEVICE);

    XAxiDma_IntrDisable(&(p_handler->axi_dma), XAXIDMA_IRQ_ALL_MASK,
                       XAXIDMA_DEVICE_TO_DMA);

    XAxiDma_IntrEnable(&(p_handler->axi_dma), XAXIDMA_IRQ_ALL_MASK,
                      XAXIDMA_DMA_TO_DEVICE);

    XAxiDma_IntrEnable(&(p_handler->axi_dma), XAXIDMA_IRQ_ALL_MASK,
                      XAXIDMA_DEVICE_TO_DMA);

    return XST_SUCCESS;
}

axi_dma_intr_poll.h

#ifndef INC_AXI_DMA_POLL_H
#define INC_AXI_DMA_POLL_H

#include "xaxidma.h"
#include "xscugic.h"

#include "platform_.h"

typedef struct {
    uint32_t *p_tx_buf;
    uint32_t *p_rx_buf;
    size_t size;
} axi_dma_poll_str;

typedef struct {
    uint32_t tx_intr_id;
    uint32_t rx_intr_id;
    void (*rx_intr_handler)(void *);
    void (*tx_intr_handler)(void *);
    uint32_t dma_id;
} axi_dma_init_str;

typedef struct {
    XAxiDma axi_dma;
    XAxiDma_Config *p_config;
    XScuGic scu_gic;
    XScuGic_Config *p_intc_config;
} axi_dma_handler_str;

int axi_dma_init(axi_dma_init_str *p_init, axi_dma_handler_str *p_handler);
int axi_dma_poll(axi_dma_poll_str *p_poll, XAxiDma *p_axi_dma, uint32_t dma_id);
int axi_dma_release(XScuGic *p_scu_gic, uint32_t tx_intr_id, uint32_t rx_intr_id);

#endif

beginner – Java Macro Program

I’ve created a macro program using java applet, I’m planning on adding more ways to add a macro but I’ve been stuck on the “Key binds” part of my plan. I’ve tried many ways of adding a keybind to start the macro when the applet window is not focused/selected. I want to use a keybind to activate the macro as if it were the button I’ve added labeled “Run Macro”, but make it activate even if the applet is not selected as a window, meaning I want to for example be inside the game Minecraft and then just press “CTRL+P” which activates the macro.

Question:
How would I add keybinds that affect the applet even when the applet is not the “active window”?

Note:
I did use JDK 8(for applet aka appletviewer.exe) and modified the policy to allow permission for macro robot commands.

Code:
MacroApplet.java

//Robot Imports
import java.awt.Robot;
import java.awt.AWTException;
import java.awt.event.KeyEvent;

//Applet Imports
import java.applet.Applet;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.*;
import java.applet.*;

public class MacroApplet extends Applet implements ActionListener
{
    int buttonpresses=0;
    int counter=0;
    int timee=0;

    Button button1 = new Button ("Start");

////////////////////////////////////////////////////////////////////////////////
////
        Label Long = new Label ("                                                                                                                                                                                                                                                                                     ");
        Label Long1 = new Label ("                                                                                                                                                                                                                                                                                     ");
        Label Long2 = new Label ("                                                                                                                                                                                                                                                                                     ");
        Label Long3 = new Label ("                                                                                                                                                                                                                                                                                     ");
        Label Long4 = new Label ("                                                                                                                                                                                                                                                                                     ");
        Label Long5 = new Label ("                                                                                                                                                                                                                                                                                     ");
        Label Long6 = new Label ("                                                                                                                                                                                                                                                                                     ");
        Label Long7 = new Label ("                                                                                                                                                                                                                                                                                     ");
        Label Long8 = new Label ("                                                                                                                                                                                                                                                                                     ");
        Label Long9 = new Label ("                                                                                                                                                                                                                                                                                     ");
        Label Long10 = new Label ("                                                                                                                                                                                                                                                                                     ");
////
////////////////////////////////////////////////////////////////////////////////

    Label status = new Label ("Waiting..");

    Label inputkeys = new Label ("Input keys:");
    TextField textfield1 = new TextField ("");
    Label Lwaittime = new Label ("Start waittime:");
    TextField TFwaittime = new TextField ("1500");
    Label Lholdtime = new Label ("Key holdtime:");
    TextField TFholdtime = new TextField ("500");
    Label Lendtime = new Label ("Key waittime:");
    TextField TFendtime = new TextField ("250");

    Checkbox M1 = new Checkbox("At start click");
    Checkbox M2 = new Checkbox("At end click");

    Label Plays = new Label ("Run amount:");
    TextField Rtimes = new TextField ("1");

////////////////////////////////////////////////////////////////////////////////
////Check invis characters (only for testing)
    public void paint (Graphics g)
    {
        //setBackground(Color.gray);
    }
////
////////////////////////////////////////////////////////////////////////////////


    public void init ()
    {
        add(button1);
        button1.addActionListener(this);

////////////////////////////////////////////////////////////////////////////////
////
                    add(Long1);
                    add(Long2);
                    add(Long3);
                    add(Long4);
                    add(Long5);
                    add(Long6);
                    add(Long7);
                    add(Long8);
                    add(Long9);
                    add(Long10);
////
////////////////////////////////////////////////////////////////////////////////
        add(Plays);
        add(M1);
        add(M2);
        add(status);
        add(textfield1);
        add(Lwaittime);
        add(TFwaittime);
        add(Lholdtime);
        add(TFholdtime);
        add(TFendtime);
        add(Lendtime);

        add(Rtimes);

        add(inputkeys);
    }

    public void actionPerformed (ActionEvent e) //Method for get action
    {
        buttonpresses=buttonpresses+1;
        textfield1.setBounds(115,50,135,20);
        inputkeys.setBounds(45,50,105,20);
        button1.setLabel("Run Macro");
        button1.setBounds(145,20,80,20);
        status.setBounds(70,20,80,20);
        Lwaittime.setBounds(45,75,80,20);
        TFwaittime.setBounds(135,75,80,20);
        Lholdtime.setBounds(45,95,80,20);
        TFholdtime.setBounds(135,95,80,20);
        Lendtime.setBounds(45,115,80,20);
        TFendtime.setBounds(135,115,80,20);
        M1.setBounds(130,135,180,20);
        M2.setBounds(130,155,180,20);
        Rtimes.setBounds(130,185,40,20);
        Plays.setBounds(45,185,80,20);

////////////////////////////////////////////////////////////////////////////////
////
                        Long1.setBounds(0,0,0,0);
                        Long2.setBounds(0,0,0,0);
                        Long3.setBounds(0,0,0,0);
                        Long4.setBounds(0,0,0,0);
                        Long5.setBounds(0,0,0,0);
                        Long6.setBounds(0,0,0,0);
                        Long7.setBounds(0,0,0,0);
                        Long8.setBounds(0,0,0,0);
                        Long9.setBounds(0,0,0,0);
////
////////////////////////////////////////////////////////////////////////////////

        if (e.getSource()==button1 && buttonpresses>1)
        {
            do
            {
                String times = Rtimes.getText();
                timee=Integer.parseInt(times);

                counter=counter+1;

                status.setText("Running..");
                try
                {
                    Robot robot = new Robot();

                    //string is the input box
                    String string = textfield1.getText();
                    String stringCaps = string.toUpperCase();

                    char() chars = string.toCharArray();
                    char() charsCaps = stringCaps.toCharArray();

                    //Wait abit
                    try
                    {
                        String waittime = TFwaittime.getText();
                        int time=Integer.parseInt(waittime);

                        Thread.sleep(time);
                    }

                    catch(InterruptedException ex)
                    {
                        Thread.currentThread().interrupt();
                    }
                    //Wait abit

                    //StartMouseClickCheckBox
                    boolean checked = M1.getState();
                    if(M1.getState())
                    {
                    robot.mousePress(InputEvent.BUTTON1_MASK);
                    robot.mouseRelease(InputEvent.BUTTON1_MASK);
                    }

                    for(int i=0; i < charsCaps.length; i++)
                    {
                        if(chars(i) ==charsCaps(i))robot.keyPress(KeyEvent.VK_SHIFT);
                        robot.keyPress(charsCaps(i));

                        //Hold time
                        //Wait abit
                        try
                        {
                            String holdtime = TFholdtime.getText();
                            int time=Integer.parseInt(holdtime);

                            Thread.sleep(time);
                        }

                        catch(InterruptedException ex)
                        {
                            Thread.currentThread().interrupt();
                        }
                        //Wait abit

                        robot.keyRelease(charsCaps(i));
                        robot.keyRelease(KeyEvent.VK_SHIFT);

                        //Ending time
                        //Wait abit
                        try
                        {
                            String endtime = TFendtime.getText();
                            int time=Integer.parseInt(endtime);

                            Thread.sleep(time);
                        }

                        catch(InterruptedException ex)
                        {
                            Thread.currentThread().interrupt();
                        }
                        //Wait abit
                    }
                    //EndMouseClickCheckBox
                    boolean on = M2.getState();
                    if(M2.getState())
                    {
                    robot.mousePress(InputEvent.BUTTON1_MASK);
                    robot.mouseRelease(InputEvent.BUTTON1_MASK);
                    }
                    status.setText("Completed!");
                }
            catch (AWTException s)
            {
                s.printStackTrace();
            }
        }while(timee!=counter); counter=0;
        }
    }
}

Thanks in advance for any tips or help on the keybinds part of my project!

First c program: Snake with ncurses

Six month ago I started studying C as my first programming language and a couple of weeks ago I decided to write snake as my first program. The program is written with ncurses and contains four modules: main, layout, controls and gameplay. I haven’t added any features yet (score, pause, welcome screen etc.).

Since it is my first program I would really appreciate any comments on how to improve my code or make it more efficient. You may also comment on the program design on a more general level. Many thanks!

main.c

#define _DEFAULT_SOURCE

#include "layout.h"
#include "controls.h"
#include "gameplay.h"
#include <unistd.h>
#include <ctype.h>

struct snake *head = NULL;
struct food cheese;
chtype body;
int snakey = 5;
int snakex = 5;
int ch;
bool horizontal = true;
bool run = true;

void init_game(void);
int delay(int csec, bool horizontal);
bool check_game(void);
bool eat_cheese();
void change_direction(void);
void update_window(void);

int main(void)
{
    srand(time(0));

    init_game();
    generate_cheese(&cheese, head);
    direction = right;

    while (true) {

        if (check_game())
            break;
        
        if (eat_cheese())
            continue;

        ch = delay(10, horizontal);
        if (ch != ERR) {
            delay(7, horizontal);
        }
        if (tolower(ch) == 'q')
            break;

        change_direction();
        update_window();
    }

    delay(100, horizontal);
    endwin();
    return 0;
}

void init_game(void)
{
    WIN win;

    system("resize -s 31 100");
    initscr();
    raw();
    keypad(stdscr, true);
    nodelay(stdscr, true);
    noecho();
    curs_set(false);
    win_params(&win);
    create_box(&win);
    refresh();

}

int delay(int csec, bool horizontal)
{
    int ch;

    for (int i = 0; i < csec; i++) {
        ch = getch();
        if (horizontal == true) {
            if (ch == KEY_UP | ch == KEY_DOWN) {
                return ch;
            }
        } else if (horizontal == false) {
            if (ch == KEY_LEFT | ch == KEY_RIGHT) {
                return ch;
            }
        }
        if (ch == 'q') {
            return ch;
        }
        flushinp();
        usleep(10000);
    }
    return ERR;
}

bool check_game(void)
{
    if (border_limit(head) || autocannibalism(head, snakey, snakex)) {
        mvprintw(head->y, head->x, "*");
        return true;
    }
    return false;

}

bool eat_cheese()
{

    if (cheese.y == snakey && cheese.x == snakex) {
        direction(&snakey, &snakex, &body);
        push_to_snake(&head, snakey, snakex, body);
        generate_cheese(&cheese, head);
        print_window(head, cheese);
        return true;
        }
    return false;
}

void change_direction(void)
{
    switch(ch) {
        case KEY_UP: 
             direction = up;
             horizontal = false;
             break;
        case KEY_DOWN: 
             direction = down;
             horizontal = false;
            break;
        case KEY_LEFT: 
            direction = left;
            horizontal = true;
            break;
        case KEY_RIGHT: 
            direction = right;
            horizontal = true;
            break;
    }
}

void update_window(void)
{
    direction(&snakey, &snakex, &body);
    pop_from_snake(&head);
    push_to_snake(&head, snakey, snakex, body);
    print_window(head, cheese);
}

layout.h

#ifndef LAYOUT_H
#define LAYOUT_H

#include <ncurses.h>

#define BORDER_STARTY 2
#define BORDER_STARTX 2
#define BORDER_HEIGHT 27
#define BORDER_WIDTH 96

typedef struct _win_border_struct {
    chtype ls, rs, ts, bs,
           tl, tr, bl, br;
} WIN_BORDER;

typedef struct _WIN_struct {
    int startx, starty;
    int height, width;
    WIN_BORDER border;
} WIN;

void win_params(WIN *p_win);
void create_box(WIN *p_win);

#endif

layout.c

#include "layout.h"

void win_params(WIN *p_win)
{
    p_win->height = BORDER_HEIGHT;
    p_win->width = BORDER_WIDTH;
    p_win->starty = BORDER_STARTY;
    p_win->startx = BORDER_STARTX;

    p_win->border.ls = ACS_VLINE;
    p_win->border.rs = ACS_VLINE;
    p_win->border.ts = ACS_HLINE;
    p_win->border.bs = ACS_HLINE;
    p_win->border.tl = ACS_ULCORNER;
    p_win->border.tr = ACS_URCORNER;
    p_win->border.bl = ACS_LLCORNER;
    p_win->border.br = ACS_LRCORNER;
}

void create_box(WIN *p_win)
{
    int x, y, w, h;

    x = p_win->startx;
    y = p_win->starty;
    w = p_win->width;
    h = p_win->height;

    mvaddch(y, x, p_win->border.tl);
    mvaddch(y, x + w, p_win->border.tr);
    mvaddch(y + h, x, p_win->border.bl);
    mvaddch(y + h, x + w, p_win->border.br);
    mvhline(y, x + 1, p_win->border.ts, w - 1);
    mvhline(y + h, x + 1, p_win->border.bs, w - 1);
    mvvline(y + 1, x, p_win->border.ls, h - 1);
    mvvline(y + 1, x + w, p_win->border.rs, h - 1);

    refresh();

}

controls.h

#ifndef CONTROLS_H
#define CONTROLS_H

#include "layout.h"

void (*direction)(int *snakey, int *snakex, chtype *body);
void left(int *snakey, int *snakex, chtype *body);
void right(int *snakey, int *snakex, chtype *body);
void up(int *snakey, int *snakex, chtype *body);
void down(int *snakey, int *snakex, chtype *body);

#endif

controls.c

#include "controls.h"

void left(int *snakey, int *snakex, chtype *body)
{
    (*snakex)--;
    *body = ACS_CKBOARD;
}

void right(int *snakey, int *snakex, chtype *body)
{
    (*snakex)++;
    *body = ACS_CKBOARD;
}

void up(int *snakey, int *snakex, chtype *body)
{
    (*snakey)--;
    *body = ACS_CKBOARD;
}

void down(int *snakey, int *snakex, chtype *body)
{
    (*snakey)++;
    *body = ACS_CKBOARD;
}

gameplay.h

#ifndef GAMEPLAY_H
#define GAMEPLAY_H

#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#include "layout.h"

struct food {
    int y;
    int x;
};

struct snake {
    chtype body;
    int x;
    int y;
    struct snake *next;
};

bool border_limit(struct snake *head);
bool autocannibalism(struct snake *head, int snakey, int snakex);
void generate_cheese(struct food *cheese, struct snake *head);
bool check_overlap(struct food *cheese, struct snake *head);
void push_to_snake(struct snake **head, int y, int x, chtype body);
void pop_from_snake(struct snake **head);
void clear_window(struct food cheese);
void print_window(struct snake *head, struct food cheese);

#endif

gameplay.c

#include "gameplay.h"

#define CHEESE ACS_DIAMOND


bool border_limit(struct snake *head)
{
    if (head == NULL) {
        return FALSE;
    } else if (head->y == BORDER_STARTY | head->y == BORDER_HEIGHT + BORDER_STARTY |
        head->x == BORDER_STARTX | head->x == BORDER_WIDTH + BORDER_STARTX) {
        return TRUE;
    }

    return FALSE;
}

bool autocannibalism(struct snake *head, int snakey, int snakex)
{
    if (head == NULL) {
        return FALSE;
    } else {
        head = head->next;
    }

    while (head) {
        if (snakey == head->y && snakex == head->x) {
            return TRUE;
        }
        head = head->next; 
    }

    return FALSE;
}

void generate_cheese(struct food *cheese, struct snake *head)
{
    while (true) {
        cheese->y = (rand() % (BORDER_HEIGHT - 1)) + BORDER_STARTY + 1; 
        cheese->x = (rand() % (BORDER_WIDTH - 1)) + BORDER_STARTX + 1;

        if (check_overlap(cheese, head)) {
            continue;
        } else {
            mvaddch(cheese->y, cheese->x, CHEESE);
            break;
        }
    }
}

bool check_overlap(struct food *cheese, struct snake *head)
{
    while (head != NULL) {
        if (cheese->y == head->y && cheese->x == head->x) {
            return true;
        }
        head = head->next;
    }
    return false;
}

void push_to_snake(struct snake **head, int y, int x, chtype body)
{
    struct snake *new_snake;

    new_snake = malloc(sizeof(struct snake));
    if (new_snake == NULL) {
        printf("Error: malloc failed in %s", __func__);
        exit(EXIT_FAILURE);

    }

    new_snake->body = body;
    new_snake->y = y;
    new_snake->x = x;
    new_snake->next = *head;
    *head = new_snake;
}

void pop_from_snake(struct snake **head)
{
    struct snake *tail = *head;

    while (tail != NULL) {
        if (tail->next == NULL) {
            *head = tail->next;
            free(tail);
            break;
        }
        head = &tail->next;
        tail = tail->next;
    }
}

void clear_window(struct food cheese)
{
    for (int i = BORDER_STARTX + 1; i < BORDER_HEIGHT + 2; i++) {
        for (int j = BORDER_STARTY + 1; j < BORDER_WIDTH + 2; j++) {
                mvprintw(i, j, " ");
        }
    }
    mvaddch(cheese.y, cheese.x, CHEESE);
}

void print_window(struct snake *head, struct food cheese)
{
    clear_window(cheese);

    while (head) {
        mvaddch(head->y, head->x, head->body);
        head = head->next;
    }

    refresh();
}