/***************************************************************************
 * Copyright 1995, Technion, Israel Institute of Technology
 * Electrical Eng, Software Lab.
 * Author:    Michael Veksler.
 ***************************************************************************
 * File:      dde_proc.c
 * Purpose :  DDE signals and processes functionality for DDE
 ***************************************************************************
 */
#ifdef CONFIG_IPC

#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#define msgbuf mymsg
#endif

#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/msg.h>
#include "wintypes.h"
#include "win.h"
#include "shm_semaph.h"
#include "shm_main_blk.h"
#include "dde_proc.h"
#include "dde_mem.h"
#include "dde.h"
#include "debug.h"
#include "xmalloc.h"

int curr_proc_idx= -1;

enum stop_wait_op stop_wait_op=CONT;
int had_SIGUSR2 = 0;
sigjmp_buf env_get_ack;
sigjmp_buf env_wait_x;

#define IDX_TO_HWND(idx)  (0xfffe - (idx))
#define HWND_TO_IDX(wnd)  (0xfffe - (wnd))
#define DDE_WIN_INFO(win) ( main_block->windows[HWND_TO_IDX(win)] )
#define DDE_WIN2PROC(win) ( DDE_WIN_INFO(win).proc_idx )
#define DDE_IsRemoteWindow(win)	 (  (win)<0xffff && (win)>=(0xffff-DDE_PROCS))
#define DDE_SEND 1
#define DDE_POST 2
#define DDE_ACK	 3
#define DDE_MSG_SIZE   sizeof(MSG16)
#define FREE_WND (WORD)(-2)
#define DELETED_WND (WORD)(-3)
static char *msg_type[4]={"********", "DDE_SEND", "DDE_POST", "DDE_ACK"};

struct msg_dat {
	struct msgbuf dat;
	char filler[DDE_MSG_SIZE];
} ;

typedef struct fifo_element {
	int value;
	struct fifo_element *next;
} fifo_element;

struct fifo {
	fifo_element *first;	   /* first element in the fifo or NULL */
	fifo_element *last;	   /* last element in the fifo or NULL */
};
static struct fifo fifo = {NULL,NULL};

void dde_proc_delete(int proc_idx);

void dde_proc_add_fifo(int val)
{
  fifo_element *created;

  created= (fifo_element*) xmalloc( sizeof(fifo_element) );
  created->value = val;
  created->next = NULL;
  
  if (fifo.first==NULL) 
     fifo.first= created;
  else 
     fifo.last->next= created;
  fifo.last = created;
}

/* get an item from the fifo, and return it.
 * If fifo is empty, return -1
 */
int dde_proc_shift_fifo()
{
  int val;
  fifo_element *deleted;
  
  if (fifo.first == NULL)
     return -1;
  
  deleted= fifo.first;
  val= deleted->value;
  fifo.first= deleted->next;
  if (fifo.first == NULL)
     fifo.last= NULL;

  free(deleted);
  return val;
}

static void print_dde_message(char *desc, MSG16 *msg);

/* This should be run only when main_block is first allocated.	*/
void dde_proc_init(dde_proc proc)
{
  int proc_num;

  for (proc_num=0 ; proc_num<DDE_PROCS ; proc_num++, proc++) {
     proc->msg=-1;
     proc->sem=-1;
     proc->shmid=-1;
     proc->pid=-1;
  }
}

/* add current process to the list of processes */
void dde_proc_add(dde_proc procs)
{
  dde_proc proc;
  int proc_idx;
  TRACE(dde,"(..)\n");
  shm_write_wait(main_block->sem);

  /* find free proc_idx and allocate it */
  for (proc_idx=0, proc=procs ; proc_idx<DDE_PROCS ; proc_idx++, proc++)
     if (proc->pid==-1)
	break;			   /* found! */

  if (proc_idx<DDE_PROCS) {	   /* got here beacuse a free was found ? */
     dde_msg_setup(&proc->msg);
     proc->pid=getpid();
     curr_proc_idx=proc_idx;
     shm_sem_init(&proc->sem);
  }
  else	{
     fflush(stdout);
     WARN(dde,"Can't allocate process\n");
  }
  shm_write_signal(main_block->sem);
}

/* wait for dde - acknowledge message - or timout */
static BOOL32 get_ack()
{
    struct timeval timeout;
    int size;
    struct msg_dat ack_buff;

    /* timeout after exactly one seconf */
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    sigsetjmp(env_get_ack, 1);
    /* get here after normal execution, or after siglongjmp */

    do {			   /* loop to wait for DDE_ACK */
       had_SIGUSR2=0;
       stop_wait_op=CONT;	   /*  sensitive code: disallow siglongjmp */
       size= msgrcv( main_block->proc[curr_proc_idx].msg , &ack_buff.dat,
		     1, DDE_ACK, IPC_NOWAIT);
       if (size>=0) {
	  TRACE(msg,"get_ack: received DDE_ACK message\n");
	  return TRUE;
       }
       if (DDE_GetRemoteMessage()) {
	     had_SIGUSR2=1;  /* might have recieved SIGUSR2 */
       }
       stop_wait_op=STOP_WAIT_ACK; /* allow siglongjmp */

    } while (had_SIGUSR2);	   /* loop if SIGUSR2 was recieved */

    /* siglongjmp should be enabled at this moment */
    select( 0, NULL, NULL, NULL, &timeout );
    stop_wait_op=CONT;		   /* disallow further siglongjmp */

    /* timeout !! (otherwise there would have been a siglongjmp) */
    return FALSE;
}

/* Transfer one message to a given process */
static BOOL32 DDE_DoOneMessage (int proc_idx, int size, struct msgbuf *msgbuf)
{
  dde_proc proc= &main_block->proc[ proc_idx ];


  if (proc_idx == curr_proc_idx)
     return FALSE;

  if (kill(proc->pid,0) < 0) {
     /* pid does not exist, or not our */
     dde_proc_delete(proc_idx);
     return FALSE;
  }

  if (TRACE_ON(dde) || WARN_ON_dde) {
     MSG16 *msg=(MSG16*) &msgbuf->mtext;
     char *title;
     if (msgbuf->mtype==DDE_SEND)
	title="sending dde:";
     else if (msgbuf->mtype==DDE_POST)
	title="posting dde:";
     else
	title=NULL;
     if (title)
	 print_dde_message(title, msg);
     else
       WARN(dde, "Unknown message type=0x%lx\n", msgbuf->mtype);
  }
  TRACE(msg, "to proc_idx=%d (pid=%d), queue=%u\n",
	       proc_idx, proc->pid, (unsigned)proc->msg);
  if ( proc->msg != -1) {
     TRACE(msg, "doing...(type=%s)\n", msg_type[msgbuf->mtype]);
     size=msgsnd (proc->msg, msgbuf, size, 0);

     if (size<0) {
	 fflush(stdout);
	 perror("msgsnd");
     }
     kill(proc->pid,SIGUSR2);	   /* tell the process there is a message */

     TRACE(msg, "Trying to get acknowledgment from msg queue=%d\n",
		  proc->msg);
     Yield16();			/* force task switch, and */
				/* acknowledgment sending */
     if (get_ack()) {
	return TRUE;
     } else {
	fflush(stdout);
	WARN(dde,"get_ack: DDE_DoOneMessage: timeout\n");
	return FALSE;
     }
  }
  else {
     WARN(msg, "message not sent, target has no message queue\n");
     return FALSE;
  }
}

/* Do some sort of premitive hash table */
static HWND16 HWND_Local2Remote(HWND16 orig)
{
  int dde_wnd_idx;
  int deleted_idx= -1;
  WND_DATA *tested;
  WND_DATA *deleted= NULL;
  int i;
  
  dde_wnd_idx= orig % DDE_WINDOWS;
  for ( i=0 ; i < DDE_WINDOWS ; i++, dde_wnd_idx++) {
    if (dde_wnd_idx >= DDE_WINDOWS)
      dde_wnd_idx -= DDE_WINDOWS; /* wrap-around */
    
    tested= &main_block->windows[ dde_wnd_idx ];
    if (tested->proc_idx == FREE_WND)
      break;
    
    if (deleted == NULL && tested->proc_idx == DELETED_WND) {
      deleted= tested;
      deleted_idx= dde_wnd_idx;
    } else if (tested->wnd == orig && tested->proc_idx == curr_proc_idx) {
      return IDX_TO_HWND(dde_wnd_idx);
    }
  }
  if (deleted != NULL)	{	/* deleted is preferable */
    /* free item, allocate it */
    deleted->proc_idx= curr_proc_idx;
    deleted->wnd = orig;
    return IDX_TO_HWND(deleted_idx);
  }
  if (tested->proc_idx == FREE_WND) {
    tested->proc_idx= curr_proc_idx;
    tested->wnd = orig;
    return IDX_TO_HWND(dde_wnd_idx);
  }

  WARN(dde, "Can't map any more windows to DDE windows\n");
  return 0;			
}

static BOOL32 DDE_DoMessage( MSG16 *msg, int type )
{
  int proc_idx;

  MSG16 *remote_message;
  struct msg_dat msg_dat;
  BOOL32 success;
  
  if (msg->wParam == 0)
      return FALSE;
  
  if (main_block==NULL) {
    if (msg->message >=  WM_DDE_FIRST && msg->message <= WM_DDE_LAST) 
      DDE_IPC_init();
    else 
      return FALSE;
  }


  if (msg->wParam == (HWND16)-1)
     return FALSE;

  if ( ! DDE_IsRemoteWindow(msg->hwnd) && msg->hwnd!= (HWND16)-1)
     return FALSE;

  TRACE(msg, "(hwnd=0x%x,msg=0x%x,..) - %s\n",
	       (int)msg->hwnd,(int)msg->message,msg_type[type]);
  

  TRACE(msg, "(hwnd=0x%x,msg=0x%x,..) -- HWND_BROADCAST !\n",
	       (int)msg->hwnd,(int)msg->message);
  remote_message=(void*)&msg_dat.dat.mtext;
  
  memcpy(remote_message, msg, sizeof(*msg));
  remote_message->wParam= HWND_Local2Remote(msg->wParam);
  if (remote_message->wParam == 0)
    return FALSE;
  
  msg_dat.dat.mtype=type;

  if (msg->hwnd == (HWND16)-1) {
     success= FALSE;
     for ( proc_idx=0; proc_idx < DDE_PROCS ; proc_idx++) {
	if (proc_idx == curr_proc_idx)
	   continue;
	if (main_block->proc[ proc_idx ].msg != -1)
	   success|=DDE_DoOneMessage(proc_idx, DDE_MSG_SIZE, &msg_dat.dat);
     }
     return success;
  } else {
     return DDE_DoOneMessage(DDE_WIN2PROC(msg->hwnd), DDE_MSG_SIZE,
			     &msg_dat.dat);
  }
}

BOOL32 DDE_SendMessage( MSG16 *msg)
{
  return DDE_DoMessage(msg, DDE_SEND);
}

BOOL32 DDE_PostMessage( MSG16 *msg)
{
  return DDE_DoMessage(msg, DDE_POST);
}


void dde_proc_send_ack(HWND16 wnd, BOOL32 val) {
   int proc,msg;

   static struct msgbuf msg_ack={DDE_ACK,{'0'}};

   proc=DDE_WIN2PROC(wnd);
   msg=main_block->proc[proc].msg;
   TRACE(msg,"sending ACK to wnd=%4x, proc=%d,msg=%d, pid=%d\n",
		wnd,proc,msg,main_block->proc[proc].pid);

   msg_ack.mtext[0]=val;
   msgsnd (msg, &msg_ack, 1, 0);
   kill(main_block->proc[proc].pid, SIGUSR2);
}

/* return true (non zero) if had a remote message */
#undef DDE_GetRemoteMessage

int DDE_GetRemoteMessage()
{
  static int nesting=0;		   /* to avoid infinite recursion */

  MSG16 *remote_message;
  int size;
  struct msg_dat msg_dat;
  BOOL32 was_sent;		   /* sent/received */
  BOOL32 passed;
  WND *wndPtr;

  if (curr_proc_idx==-1)	   /* do we have DDE initialized ? */
     return 0;

  if (nesting>10) {
     fflush(stdout);
     ERR(msg, "suspecting infinite recursion, exiting");
     return 0;
  }

  remote_message=(void*)&msg_dat.dat.mtext;

  /* test for SendMessage */
  size= msgrcv( main_block->proc[curr_proc_idx].msg , &msg_dat.dat,
		DDE_MSG_SIZE, DDE_SEND, IPC_NOWAIT);

  if (size==DDE_MSG_SIZE) {	   /* is this a correct message (if any) ?*/
     was_sent=TRUE;
     TRACE(msg, "DDE:receive sent message. msg=%04x wPar=%04x"
		  " lPar=%08lx\n",
		  remote_message->message, remote_message->wParam,
		  remote_message->lParam);
  } else {
     size= msgrcv( main_block->proc[curr_proc_idx].msg , &msg_dat.dat,
		   DDE_MSG_SIZE, DDE_POST, IPC_NOWAIT);

     if (size==DDE_MSG_SIZE) {	   /* is this a correct message (if any) ?*/
	was_sent=FALSE;
	TRACE(msg, "DDE:receive posted message. "
		    "msg=%04x wPar=%04x lPar=%08lx\n",
		    remote_message->message, remote_message->wParam,
		    remote_message->lParam);
     }
     else
	return 0;		   /* no DDE message found */
  }

  /* At this point we are sure that there is a DDE message,
   * was_sent is TRUE is the message was sent, and false if it was posted
   */

  nesting++;

  if (TRACE_ON(dde)) {
     char *title;
     if (was_sent)
	title="receive sent dde:";
     else
	title="receive posted dde:";
     print_dde_message(title, remote_message);
  }

  if (remote_message->hwnd != (HWND16) -1 ) {
    HWND16 dde_window= DDE_WIN_INFO(remote_message->hwnd).wnd;
     /* we should know exactly where to send the message (locally)*/
     if (was_sent) {
	TRACE(dde, "SendMessage(wnd=0x%04x, msg=0x%04x, wPar=0x%04x,"
		    "lPar=0x%08x\n", dde_window, remote_message->message,
		    remote_message->wParam, (int)remote_message->lParam);

	/* execute the recieved message */
	passed= SendMessage16(dde_window, remote_message->message,
			    remote_message->wParam, remote_message->lParam);

	/* Tell the sended, that the message is here */
	dde_proc_send_ack(remote_message->wParam, passed);
     }
     else {
	passed= PostMessage16(dde_window, remote_message->message,
			    remote_message->wParam, remote_message->lParam);
	if (passed == FALSE) {
	   /* Tell the sender, that the message is here, and failed */
	    dde_proc_send_ack(remote_message->wParam, FALSE);
	}
	else {
	   /* ack will be sent later, at the first peek/get message  */
	   dde_proc_add_fifo(remote_message->wParam);
	}
     }
     nesting--;
     return 1;
  }

  /* iterate through all the windows */
  for (wndPtr = WIN_FindWndPtr(GetTopWindow32(GetDesktopWindow32()));
       wndPtr != NULL;
       wndPtr = wndPtr->next)
  {
     if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION) {
	if (was_sent)
	   SendMessage16( wndPtr->hwndSelf, remote_message->message,
			remote_message->wParam, remote_message->lParam );
	else
	   PostMessage16( wndPtr->hwndSelf, remote_message->message,
                        remote_message->wParam, remote_message->lParam );
     } /* if */
  } /* for */

  /* replay with DDE_ACK after broadcasting in DDE_GetRemoteMessage */
  dde_proc_send_ack(remote_message->wParam, TRUE);

  nesting--;
  return 1;
}

int dde_reschedule()
{
    int ack_wnd;
	
    ack_wnd= dde_proc_shift_fifo();
    if (ack_wnd != -1) {
	dde_proc_send_ack(ack_wnd, TRUE);
	usleep(10000);		/* force unix task switch */
	return 1;
    }
    return 0;
}
void dde_msg_setup(int *msg_ptr)
{
  *msg_ptr= msgget (IPC_PRIVATE, IPC_CREAT | 0700);
  if (*msg_ptr==-1)
     perror("dde_msg_setup fails to get message queue");
}

/* do we have dde handling in the window ?
 * If we have, atom usage will make this instance of wine set up
 * it's IPC stuff.
 */
void DDE_TestDDE(HWND16 hwnd)	   
{
  static in_test = 0;
  if (in_test++) return;
  if (main_block != NULL) {
     in_test--;
     return;
  }
  TRACE(msg,"(0x%04x)\n", hwnd);
  if (hwnd==0)
      hwnd=-1;
  /* just send a message to see how things are going */
  SendMessage16( hwnd, WM_DDE_INITIATE, 0, 0);
  in_test--;
}

void dde_proc_delete(int proc_idx)
{
  dde_proc_done(&main_block->proc[proc_idx]);
}
void stop_wait(int a)
{

  had_SIGUSR2=1;
  switch(stop_wait_op) {
    case STOP_WAIT_ACK:
      siglongjmp(env_get_ack,1);
      break;  /* never reached */
    case STOP_WAIT_X:
      siglongjmp(env_wait_x,1);
      break;  /* never reached */
    case CONT:
      /* do nothing */
  }
}

static void print_dde_message(char *desc, MSG16 *msg)
{
/*    extern const char *MessageTypeNames[];*/
    extern int debug_last_handle_size;
    WORD wStatus,hWord;
    void *ptr;
    DDEACK *ddeack;
    DDEADVISE *ddeadvise;
    DDEDATA *ddedata;
    DDEPOKE *ddepoke;
    dbg_decl_str(dde, 2048);

    if (is_dde_handle(msg->lParam & 0xffff) )
	ptr=DDE_AttachHandle(msg->lParam&0xffff, NULL);
    else
	ptr =NULL;
    wStatus=LOWORD(msg->lParam);
    hWord=HIWORD(msg->lParam);

    dsprintf(dde,"%s", desc);
    dsprintf(dde,"%04x %04x==%s %04x %08lx ",
	    msg->hwnd, msg->message,"",/*MessageTypeNames[msg->message],*/
	    msg->wParam, msg->lParam);
    switch(msg->message) {
      case WM_DDE_INITIATE:
      case WM_DDE_REQUEST:
      case WM_DDE_EXECUTE:
      case WM_DDE_TERMINATE:
	/* nothing to do */
	break;
      case WM_DDE_ADVISE:
	/* DDEADVISE: hOptions in WM_DDE_ADVISE message */
	if (ptr) {
	   ddeadvise=ptr;
	   dsprintf(dde,"fDeferUpd=%d,fAckReq=%d,cfFormat=0x%x",
		   ddeadvise->fDeferUpd, ddeadvise->fAckReq,
		   ddeadvise->cfFormat);
	} else
	   dsprintf(dde,"NO-DATA");
	dsprintf(dde," atom=0x%x",hWord);
	break;

      case WM_DDE_UNADVISE:
	dsprintf(dde,"format=0x%x, atom=0x%x",wStatus,hWord);
	break;
      case WM_DDE_ACK:
	ddeack=(DDEACK*)&wStatus;
	dsprintf(dde,"bAppReturnCode=%d,fBusy=%d,fAck=%d",
		ddeack->bAppReturnCode, ddeack->fBusy, ddeack->fAck);
	if (ddeack->fAck)
	   dsprintf(dde,"(True)");
	else
	   dsprintf(dde,"(False)");
	break;

      case WM_DDE_DATA:
	if (ptr) {
	   ddedata=ptr;
	   dsprintf(dde,"fResponse=%d,fRelease=%d,"
		   "fAckReq=%d,cfFormat=0x%x,value=\"%.*s\"",
		   ddedata->fResponse, ddedata->fRelease,
		   ddedata->fAckReq, ddedata->cfFormat,
		   debug_last_handle_size- (int)sizeof(*ddedata)+1,
		   ddedata->Value);
	} else
	   dsprintf(dde,"NO-DATA");
	dsprintf(dde," atom=0x%04x",hWord);
	break;

      case WM_DDE_POKE:
	if (ptr) {
	   ddepoke=ptr;
	   dsprintf(dde,"fRelease=%d,cfFormat=0x%x,value[0]='%c'",
		   ddepoke->fRelease, ddepoke->cfFormat, ddepoke->Value[0]);
	} else
	   dsprintf(dde,"NO-DATA");
	dsprintf(dde," atom=0x%04x",hWord);
	break;
    }
    TRACE(dde,"%s\n", dbg_str(dde));
}

void dde_proc_done(dde_proc proc)
{
  if (proc->msg != -1)
     msgctl(proc->msg, IPC_RMID, NULL);
  proc->msg=-1;
  proc->pid=-1;
  shm_delete_chain(&proc->shmid);
  shm_sem_done(&proc->sem);
}

/* delete entry, if old junk */
void dde_proc_refresh(dde_proc proc)
{
  if (proc->pid == -1)		  
     return;
  
  if (kill(proc->pid, 0) != -1)
     return;

  /* get here if entry non empty, and the process does not exist */
  dde_proc_done(proc);
}

void dde_wnd_setup()
{
  int i;

  for (i=0 ; i < DDE_WINDOWS ; i++)
    main_block->windows[i].proc_idx = FREE_WND;
}

static BOOL32 DDE_ProcHasWindows(int proc_idx)
{
  WND_DATA *tested;
  int i;
  
  for ( i=0 ; i < DDE_WINDOWS ; i++) {
    tested= &main_block->windows[ i ];
    
    if (tested->proc_idx == proc_idx) 
      return TRUE;
  }
  return FALSE;
}
/* Look for hwnd in the hash table of DDE windows,
 * Delete it from there. If there are no more windows for this
 * process, remove the process from the DDE data-structure.
 * If there are no more processes - delete the whole DDE struff.
 *
 * This is inefficient, but who cares for the efficiency of this rare
 * operation... 
 */
void DDE_DestroyWindow(HWND16 hwnd)
{
  int dde_wnd_idx;
  WND_DATA *tested;
  int i;
  
  if (main_block == NULL)
    return;
  
  dde_wnd_idx= hwnd % DDE_WINDOWS;
  
  for ( i=0 ; i < DDE_WINDOWS ; i++, dde_wnd_idx++) {
    if (dde_wnd_idx >= DDE_WINDOWS)
      dde_wnd_idx -= DDE_WINDOWS; /* wrap-around */
    
    tested= &main_block->windows[ dde_wnd_idx ];
    if (tested->proc_idx == FREE_WND)
      return;			/* No window will get deleted here */
    
    if (tested->wnd == hwnd && tested->proc_idx == curr_proc_idx) {
      dde_reschedule();
      tested->proc_idx= DELETED_WND;
      if (DDE_ProcHasWindows( curr_proc_idx ))
	return;
      while (dde_reschedule())	/* make sure there are no other */
				/* processes waiting for acknowledgment */
	;
      dde_proc_delete( curr_proc_idx );
      if (DDE_no_of_attached() == 1)
	shm_delete_all(-1);
      else {
	shmdt( (void *) main_block);
	main_block= NULL;
      }
      return;
    }
  }
}

#endif  /* CONFIG_IPC */
